A customisable terminal based input display for MKW ghost files. Currently the image processing backend is done with Pillow but this is extremely limiting (and slow?) so this might be changed in the future.
- Have Python installed, download here
- Have the
Pillowlibrary installed, after installing Python runpip install Pillow - Have
ffmpeg- Windows: Download
ffmpegfrom here and place theffmpeg.exein the same folder asmain.py - Linux: Install
ffmpegthrough your package manager
- Windows: Download
The main command is python main.py -l <layout> -g <ghost_file> where:
<layout>is the name of the layout you want to use (the name of the folder inlayouts)<ghost_file>is the path to the ghost file you want to make a video of. Support formats are:rkg,dtm,csv,txt
This will generate a video in the same folder as main.py. There are a few video settings you can specify, these can be found in src/CONFIG.py:
VIDEO_FRAME_RATE: the video frame rateVIDEO_EXTENSION: the video file formatTRANSPARENT: whether the video should have a transparent background
Layouts reside in the layouts folder. To make a new layout simply create a folder there.
Make sure to check the layouts already present in this repo to get an idea of what it should look like!
In order to see what the layout looks like while you're editing, run python main.py -l <layout> -t.
This will make live updates of the config.json file.
The only file that is absolutely necessary is the config.json file which looks like this:
{
"width": "int",
"height": "int",
"bg_color": ["int", "int", "int"]
"components": [
"..."
]
}Within the components list you can add different components which visualise the ghost's inputs.
There are several default components which can be found in src/Component.py
Components should be specified as follows:
{
"name": "str",
"input_type": "str"
"info": {
"..."
}
}nameis the class name of the componentinput_typeis one of 5 types:a_btn: the A button (accelerator)b_btn: the B button (drift)l_btn: the L button (shroom)analog: the directional inputs (analog stick)trick: trick type (d-pad)
infois a dictionary containing all the data that will be passed on to the component itself. What goes in here depends on the component.
If the default components don't do exactly what you want them to, you can make your own components for your layout. Simply create a Component.py file in your layout folder and import the base Component class
from src.Component import ComponentYou can add as many components as you want in this file but they should all look something like this:
class MyComponent(Component):
# this list specifies what inputs your component supports
supported_input_types = ["a_btn", "b_btn", "l_btn", "analog", "trick"]
# this info dict is the same as the one in the config.json file!
def init_component(self, info: dict):
...
# let your component change depending on current_input
def process_input_and_draw(self, current_input):
...Let's say I don't like how the default text component uses the [0,14] range for the directional inputs and would rather have it use the [-7, 7] range. This could be done like this:
class MyAnalogText(Component):
supported_input_types = ["analog"]
# info_format is not actually used anywhere, but it gives an idea of what the info dict should contain
info_format = {
"position": list, # [x, y]
"font": str, # font file name
"size": int # font size
}
def init_component(self, info: dict):
self.info = info
self.position = tuple(info["position"])
self.canvas.load_font(self.info["font"], self.info["size"])
def process_input_and_draw(self, current_input):
new_input = (current_input[0] - 7, current_input[1] - 7)
text = f"{str(new_input )}"
self.canvas.draw_text(text, **self.info)