-
Notifications
You must be signed in to change notification settings - Fork 16
Making a prop for RasterPropMonitor
-
You need a font bitmap. The plugin treats fonts as if they were fixed width, so it's best to take a fixed width font to start with. CBFG works, and Fixedsys Excelsior is a nice font, but there are other programs to do the same thing and probably fonts more suitable to your taste.
Every letter is assumed to occupy a block of fontLetterWidth by fontLetterHeight pixels on the bitmap. Font texture size must be evenly divisible by fontLetterWidth/fontLetterHeight respectively. For Unity reasons, the font bitmap has to have sizes that are a power of 2, but it doesn't have to be square. Characters are read from the font left to right, top to bottom, with the bottom left character being character number 32 (space). Characters 128-159 are skipped due to peculiarities of how KSP treats strings.
-
You need a model for your screen. If it's to have buttons, they need to be named colliders and isTrigger on them enabled. The screen must be a named transform, arranged in such a way that the texture's 0,1 coordinates are the top left corner of the screen. It must already have a texture in the layer ("_MainTex", "_Emissive", etc) that the plugin will replace. To save memory, that placeholder texture should be the minimum size possible, which for KSP appears to be 32x32 pixels.
Monitors are created using two modules: RasterPropMonitor and RasterPropMonitorGenerator in a prop configuration file. RasterPropMonitor takes care of the display, while RasterPropMonitorGenerator feeds it with the data to display. It is perfectly feasible to write your own plugin to completely replace RasterPropMonitorGenerator, (see source for helpful comments) and do things your way, but you probably don't want to.
There's one more module you will need, JSIInternalPersistence. Unlike the other two, it's a PartModule, not an InternalModule and requires no configuration. You just need to add it to the pod that will be hosting your IVA.
- screenTransform -- the name of the screen object.
- textureLayerID -- Unity name of a texture ID in the object's material that the screen will be printed on. Defaults to "_MainTex".
- fontTransform -- Where to get the font bitmap. You can either place a texture somewhere in GameData and refer to it exactly like you would in a MODEL configuration node (KSP reads in everything that looks like a texture and is stored outside of a PluginData directory, and assigns it an URL) or put the texture on a model transform and give the name of that transform.
- blankingColor -- R,G,B,A of a color that will be used to blank out the screen between refreshes.
- screenWidth/screenHeight -- Number of characters in a line and number of lines.
- screenPixelWidth/screenPixelHeight -- Width and height of the texture to be generated for the screen.
- fontLetterWidth/fontLetterHeight -- Width and height of a font cell in pixels.
- cameraAspect -- Aspect ratio of the camera images when this screen will be used to show them. (See Setting up cameras)
Letters are printed on the screen in pixel-perfect mapping, so one pixel of a font texture will always correspond to one pixel of the generated screen texture -- as a result, you can have less characters in a line than would fit into screenPixelWidth, but can't have more.
- refreshRate -- The screen will be redrawn no more often than once this number of frames.
- refreshDataRate -- Various computationally intensive tasks will be performed once this number of frames.
- page1,page2...page8 -- Page definitions.
- button1,button2...button8 -- Button transform names that correspond to pages.
- activePage -- Page to display on startup, 0 by default. If you include JSIInternalPersistence module in your prop.cfg for the pod, the selected page will persist upon reload of the vessel. (see below)
- camera1,camera2...camera8 -- Names of cameras and their FOVs, if any. (See Setting up cameras)
You need to have at least one page (page1). Clicking on button2 will cause page2 to be rendered, etc. If there is a button option, but no corresponding page defined, the screen will be blanked.
Pages can be defined in one of two ways -- by referencing a text file that contains a complete screen definition, or directly in the page parameter. You really want to use the text file, unless your line is particularly short. Text file reference is just like a texture URL, the only difference is that it must have a file extension.
If you wish to insert a line break in the screen definition written directly in a prop config file, you need to replace it with "$$$". If you wish to use the { and } format string characters in such a screen definition, you need to replace { with <= and } with =>, because KSP mangles them upon reading from prop.cfg files.
Multiple screens in the same IVA will share their computing modules, but this also means that the lowest refreshDataRate among all those given will be used. refreshRate remains individual per monitor.
InternalModules can't store persistent variables normally, which, with a highly detailed IVA like ALCOR, for which this was written, is a problem -- monitors want to store their currently active page, switches that turn IVA lights on and off want to store their state. This is a PartModule that stores this information for them. You want to add this module to the capsule that will be hosting the monitors and switches using JSIActionGroupSwitch. They will still work if you don't, but currently active page numbers won't get remembered and neither will switch states. There are no parameters to configure:
MODULE
{
name = JSIInternalPersistence
}
This is a highly crude solution to this problem, but it's the only one that I was able to get to work.