Skip to content

Commit

Permalink
Temp
Browse files Browse the repository at this point in the history
  • Loading branch information
Sewer56 committed Oct 23, 2022
1 parent be929f5 commit 2651d68
Show file tree
Hide file tree
Showing 13 changed files with 461 additions and 3 deletions.
2 changes: 0 additions & 2 deletions Riders.Tweakbox/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ public async void StartEx(IModLoaderV1 loader, IModConfigV1 config)
// Tweak Process Priority
var process = Process.GetCurrentProcess();
process.PriorityClass = ProcessPriorityClass.High;

//IoC.GetSingleton<CustomGearController>().Reset(false, true);
}

/* Mod loader actions. */
Expand Down
2 changes: 2 additions & 0 deletions Submodules/Sewer56.Imgui/Controls/Tooltip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ namespace Sewer56.Imgui.Controls;

public static class Tooltip
{
// TODO: Optimise this with interpolated string handler.

/// <summary>
/// Displays a tooltip if the last item was hovered over.
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions docs/BookOfTheTweakbox/charts/basic-layout.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2022-10-22T07:33:29.789Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36" etag="n-qEOJJ9jjRaBc-dsnah" version="20.5.0" type="device"><diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">5Vpbd9o4EP41nE0e4PiCjXkMJE3Tpt12YXPpS4+wZVsbYVFZ5pJfvyNbBgsMIWFD9qR5INZoNJJG33wzFjTs/nh+ydEk/sICTBuWEcwb9nnDsjrdDnxKwaIQ2I5ZCCJOgkJUEQzII1ZCQ0kzEuBUUxSMUUEmutBnSYJ9ockQ52ymq4WM6rNOUIQ3BAMf0U3pLQlEXEg9q7OSf8QkisuZTbdb9IxRqax2ksYoYLOKyL5o2H3OmCiexvM+ptJ3pV9urxa39PrBvfz0Pf2F/u59Hn69aRbGPjxnyHILHCfixaa7IzL/7HQFukGzH/eDx/PR159Ny1V7E4vSYTgA/6km4yJmEUsQvVhJe5xlSYClWQNaK51rxiYgNEH4DxZiocCAMsFAFIsxVb14TsSdHN5yVOu+0nM+V5bzxqJsJIIvKoNk877atxqWt8pxqeDsAfcZZRwkAQ5RRsGJvQClcb4HOe2eDlYHkbKM+8pbZ3fz7s2w/dP98+OnH9mUGndz2rQUzhGPsNihpzAoPV4Bqzq+S8zGGHYCChxTJMhURzRSgREt9ZZDvzEC+7AMFcNux2gZlT+1vEUZqLLX9tqu6eSfuvlis8piFV5rk3TKMCl5wjV0Q4U3NgydcY4WFbWJVEirGvBQ8cZKlOP7GVh3lLuniGbKlX2OkQB2soyzfPzJB8JTcVobE9doBMyo4RhREiXw7ANsMMCrN8VcEOCeM9UxJkFQhAxOySMa5fYkKtUuwbjTazjnIAlZIlTAdGsRuTN+5cR4XkeoalKNszRwqVFGy7TNjnaECicHoq+pw61p6wZYGKZYHHjetdHlbhz3xrlGQGWTZ3pwX57Y6mnb1CPFLCNltspPS1lczU22u935mvee6yqjxlUuGgOb93Ky1Fs+RWm6FEWaQtnKFUccnnRJKfjGWcTReLsm7GO0LpMxoh2g+ytjZUczzaPnDBS6k3kxSnWXdv7ClCHIXH/IiM/ThDxNCdfWzoUU85biNQzp2XAWE4EHE5TnhxlUVDpjhITSMhc1LDtwsBe0N7IU9HjWyHbd5Xw16KyicDv+N1H4FMqc1wKZdXSQDWcYPYzY/LgoG8Z4HV4NSR2FdVKqFbnn5LSyFLJaChS6sFhjrx28K3gqUvTc/TjRMV4JrfZ7L4xra899z22PItjYswi2Dqx5DzrlzZJwFyepcsFgoawOJEHhQynqqs+SkEQZh82y5CQ9PS5X9VAqyYrI+jWUrFASD8p95+eLy7NlK4IcaVAWLcVvlTMR9kK/jpRc38OjcF9SekHl1l17xWnXFG7dY5KU9+bwHZAkoliwZID5lPj46AhW86atFUg3Uu2XLCW+UtyZboGpBGxIuidLBRvLayA5VvIYR/4DuKtfm8tz7UuM+AtniWAo/AuQQL9fWFldR48rp71fXHmvFVfd9578a26/dlYCR7kO8w6sBJ64T6q/nrC3kPq2e64n9OGhWMF/epVhmhtEv3F1NcCQloP/z93VCy9UtsfjVv5oGi3T8HQOKUF34OXV2lWppY9/vburcqa3LUwhE1CK+dFzeoHo5T4MESNpLyAc0EPlyY9ZQEL5EKGxLFpHOEZTAkRUKQOuooRxPMz4KKM48fFqQwUUZUNaJ9JpE4oWRQdK8m5KSYDzHAQpCJawNPP75WfHfGHd+2r52Xz3b+dagq7l17fP1+abvrqb7adz4jAm/J2mxCIEdnydY3hr2as8/0O/z/FqrR6SE6G5+hq9UF/9FsG++Bc=</diagram></mxfile>
13 changes: 13 additions & 0 deletions docs/BookOfTheTweakbox/heap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Heap

!!! info

Explains how Sonic Riders' vanilla memory allocation system works.



## Changes in Tweakbox

!!! todo

To be added.
Binary file added docs/BookOfTheTweakbox/images/basic-layout.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/BookOfTheTweakbox/images/tooltip-example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions docs/BookOfTheTweakbox/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Book of the Tweakbox

Welcome to the Book of the Tweakbox (BOTT) for Riders Tweakbox. This page contains a collection of articles about the internals of both Riders Tweakbox itself, as well as Sonic Riders. The intended audience of this book is people wishing to work on Tweakbox, or wishing to understand Tweakbox and/or the base game.

| Page | Description |
| ------------------------------------------- | ---------------------------------------------------------------- |
| [Introduction](./introduction.md) | Describes the general structure/layout of Tweakbox' source code. |
| [Overlay Helper APIs](./overlay-helpers.md) | Useful APIs for creating menus in Tweakbox. |
| [Heap](./heap.md) | Describes how Sonic Riders' memory allocator works. |
303 changes: 303 additions & 0 deletions docs/BookOfTheTweakbox/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,303 @@
# Introduction

!!! info

Provides an introduction to Tweakbox' internal code structure, including how things are laid out.


## Initialization

!!! info

Provides a simplified top level view of how initialization happens in Tweakbox.

![](./images/basic-layout.png)

### Entry Point (Program)

The life of Tweakbox begins in `Program.StartEx()`, this method is responsible for the following:
- Setting up 3rd party libraries (e.g. one time method calls).
- Fetching Reloaded dependencies [e.g. [File Redirector](https://github.com/Reloaded-Project/reloaded.universal.redirector) to use with music].
- Adjusting anything runtime related.

Program then delegates to `Tweakbox`, which sets up Tweakbox' code.

### Tweakbox Entry Point (Tweakbox)

The `Tweakbox` component is responsible for the following [in order]:
- Sanity checks (e.g. ensure files don't use vanilla compression).
- Setting up UI Menus.
- Initialising all `IConfiguration`(s), `ISingletonService`(s) & `IController`(s) in this specific order.

## Components

!!! info

Defines the common kinds/types of items you'll find in Tweakbox' source code.

!!! note

Unless stated otherwise, assume components are singletons, i.e. there is only ONE instance of each configuration in memory and it's reused everywhere.

### Configs (IConfiguration)

!!! info

Stores an individual configuration for a component or a set of Tweakbox components.

Within Tweakbox' source, you will find two types of configurations, `Binary` and `JSON`.

`JSON` configurations are used when all of the data is known, and inherit from `JsonConfigBase` which provides all of the backbone code for the configuration(s).

Example:
```csharp
// JsonConfigBase inherits from IConfiguration and provides all needed boilerplate code.
public class TextureInjectionConfig : JsonConfigBase<TextureInjectionConfig, TextureInjectionConfig.Internal>
{
public class Internal
{
public bool DumpTextures = false;
public DumpingMode DumpingMode = DumpingMode.All;
public int DeduplicationMaxFiles = 2;
}

public enum DumpingMode
{
All = 0,
OnlyNew = 1,
Deduplicate = 2,
}
}
```

`Binary` configurations are typically used when the data:
- Needs to be small.
- Contains unknown values (e.g. Not fully reversed Sonic Riders' game structs).

Example `Binary` configuration:
```csharp
public unsafe class GearEditorConfig : IConfiguration
{
private static GearEditorConfig _default = new GearEditorConfig();

/// <summary>
/// Extreme gears assigned to this config.
/// </summary>
public ExtremeGear[] Gears;

/// <summary>
/// Creates the default editor config.
/// </summary>
public GearEditorConfig()
{
Gears = new ExtremeGear[Player.OriginalNumberOfGears];
Player.Gears.CopyTo(Gears, Gears.Length);
}

/// <summary>
/// Creates a <see cref="GearEditorConfig"/> from the values present in game memory.
/// </summary>
public static GearEditorConfig FromGame() => new GearEditorConfig();

/// <summary>
/// Updates the game information with the gear data stored in the class.
/// </summary>
public unsafe void Apply() => Player.Gears.CopyFrom(Gears, Player.OriginalNumberOfGears);

/// <inheritdoc />
public Action ConfigUpdated { get; set; }
public byte[] ToBytes() => LZ4.CompressLZ4Stream(StructArray.GetBytes(Gears), LZ4Level.L12_MAX);

public void FromBytes(Span<byte> bytes)
{
var outputArray = new byte[StructArray.GetSize<ExtremeGear>(Player.OriginalNumberOfGears)];
var decompressed = LZ4.DecompressLZ4Stream(outputArray, bytes, out int bytesRead);

StructArray.FromArray(decompressed, out Gears, true, Player.OriginalNumberOfGears);
ConfigUpdated?.Invoke();
}

public IConfiguration GetCurrent() => FromGame();
public IConfiguration GetDefault() => _default;
}
```

[Stores the whole array of all extreme gear data in Riders]

### Services (ISingletonService)

!!! info

Provides various utility functions to be used throughout Tweakbox.
Also a singleton.

Example API(s):

```csharp
/// <summary>
/// Keeps track of all music tracks provided by other mods (as well as the vanilla game)
/// </summary>
public class MusicService
{
/// <summary>
/// Gets the name of a random alternative track for a given file name.
/// </summary>
/// <param name="fileName">The file name for which to get a replacement track.</param>
/// <param name="includeVanilla">Whether to include vanilla tracks or not.</param>
/// <param name="includePerStageTracks">Whether to include stage-specific tracks.</param>
/// <returns>Path to the replacement track.</returns>
public unsafe string GetRandomTrack(string fileName, bool includeVanilla, bool includePerStageTracks);

/// <summary>
/// Obtains all potential candidate tracks for a given stage.
/// </summary>
/// <param name="stageId">The stage index.</param>
/// <param name="files">List of files to add the candidates to.</param>
public void GetTracksForStage(int stageId, List<string> files);
}
```

```csharp
/// <summary>
/// Converts Sonic Riders' PVRT texture format to DDS using the game's built-in converter.
/// </summary>
public class PvrtConverterService : ISingletonService
{
/// <summary>
/// Converts a texture to DDS.
/// </summary>
/// <param name="pvrtData">The PVRT texture to convert.</param>
/// <returns>DDS data generated from PVRT.</returns>
public unsafe byte[] Convert(Span<byte> pvrtData);
}
```

### Controllers (IController)

!!! info

Controllers contain all the functionality that modifies directly how the game itself functions.
These controllers usually 'hook' into the game code, by either replacing the method or injecting some assembly code.

Random Example(s):

| Controller | Description |
| ---------------------------- | ----------------------------------------------------------------------------- |
| MusicInjectionController | Replaces the music track(s) that will be loaded by the game. |
| IgnoreTurbulenceController | The 'C toggle' for ignoring turbulence if desired. |
| BorderlessWindowedController | Toggles the game's Borderless Windowed state during startup and in real time. |
| RailController | Controls the speed of the Rails. |
| AutoSectionController | Automates Left+Right inputs during automated sections. |

Within controllers there exists one special case, `EventController`. This controller is implemented mainly in x86 assembly, split over multiple files and provides callbacks which you can subscribe to that modify various game behaviours.

For example:
```csharp
EventController.SetRingsOnHit += SetRingsOnHit;
private void SetRingsOnHit(Player* player) => player->Rings = 42;
```

### Menus (IComponent)

!!! info

Menus use the `IComponent` interface and are created + registered during Tweakbox startup.

Random Example(s):

| Controller | Description |
| ---------------- | ------------------------------------------- |
| AboutMenu | Renders the about page. |
| TweakboxSettings | Renders the Tweakbox general settings menu. |
| SlipstreamDebug | Shows slipstream data in real time. |

#### Creating Menus

In practice, all menus inherit from `ComponentBase` or `ComponentBase<TConfig>`, which provide a default implementation of `IComponent`.

Sample dummy menu (via `ComponentBase`):
```csharp
// Renders
public class DummyMenu : ComponentBase
{
public override string Name { get; set; } = "Dummy Menu";
public override void Render()
{
if (ImGui.Begin(Name, ref IsEnabled(), 0))
{
// Code to render menu here
}

ImGui.End();
}
}
```

If you need to have a config for this menu, use `ComponentBase<TConfig>`.

```csharp
// InfoEditorConfig is an IConfiguration
public class InfoEditor : ComponentBase<InfoEditorConfig>, IComponent
{
public override string Name { get; set; } = "Info Editor";

// Note the constructor, it passes some stuff to base class.
public InfoEditor(IO io) : base(io, io.InfoConfigFolder, io.GetInfoConfigFiles, ".json") { }

public override void Render()
{
if (ImGui.Begin(Name, ref IsEnabled(), 0))
{
// Provides the New/Delete/Load/Save part of the menu.
ProfileSelector.Render();

// Code to render menu here
}

ImGui.End();
}
}
```

#### Registering Menus

!!! info

Custom Menus must be registered in `Tweakbox.cs` to show in the overlay.

Example:
```csharp
new MenuBarItem("Main", new List<IComponent>()
{
// Your custom menu here.
Benchmark(() => IoC.GetSingleton<DummyMenu>(), nameof(DummyMenu)),

// Previously existing menus.
Benchmark(() => IoC.GetSingleton<NetplayMenu>(), nameof(NetplayMenu)),
Benchmark(() => IoC.GetSingleton<UserGuideWindow>(), nameof(UserGuideWindow)),
Benchmark(() => IoC.GetSingleton<AboutMenu>(), nameof(AboutMenu)),
Benchmark(() => IoC.GetSingleton<OpenSourceLibraries>(), nameof(OpenSourceLibraries)),
})
```

## Projects

!!! info

Provides a listing of projects within the Tweakbox source code.

| Project | Description |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Riders.Netplay.Messages | Contains all code responsible for writing/reading individual messages over the network. |
| Riders.Netplay.Messages.Tests | Test code for messages library; can be barebones at times. |
| Riders.Tweakbox.API.SDK | Code for communicating with the [Web Server providing server browser, ranking](https://github.com/Sewer56/Riders.Tweakbox.API). |
| Riders.Tweakbox | Main mod code. |
| Riders.Tweakbox.CharacterPack.DX | Test/example mod for adding custom character behaviours. [Ports SRDX 1.0.1 char stats to Tweakbox] |
| Riders.Tweakbox.Gearpack | Test/example mod for adding custom gear behaviours. [Ports all gears from all mods released before late 2021] |
| Riders.Tweakbox.Interfaces | API for other mods to use. [Recommend Reading: Dependency Injection in Reloaded-II](https://reloaded-project.github.io/Reloaded-II/DependencyInjection_HowItWork/) |
| Sewer56.Hooks.Utilities | Helper code for manipulating game functions with x86 assembly. |
| Sewer56.Imgui | Helpers for creating menus. (Extensions for our *Dear ImGui* wrapper.) |
| Sewer56.SonicRiders | API and definitions for hacking Sonic Riders |

[Some projects have been omitted to keep the list simpler.]
Loading

0 comments on commit 2651d68

Please sign in to comment.