Some TempleOS Tweaks

Sun 05 Nov 2023

TempleOS is a hobby operating system with a lot of interesting history. I first encountered it sometime around 2015, and ever since I have found myself coming back to it every year or so. At first it's quite prickly and hard to understand. But once you have spent enough time with it, it becomes quite comfortable.

I want to write about TempleOS in depth at some other point, but for now I just want to share some tweaks that I usually make when toying around with it.

First it would help to know how to get around the code a little easier.

To find the source for any symbol in TempleOS, you can invoke the Man() function. For example if I wanted to find WINMGR_FPS as per the first tweak. I could call Man("WINMGR_FPS"); from the command line. There is also the built in Autocomplete which is capable of doing the same with a hotkey.

Higher Framerate

TempleOS has a few technical restrictions that are ideologically or religiously informed, such as the 640x480 resolution limit. As far as I'm aware, framerate is not one of those restrictions. Although I may be wrong about that.

In any case I find the overall user experience much more pleasant when the default framerate cap has been raised from 30 to 60 fps.

#define WINMGR_FPS	(60000.0/1001)
#define WINMGR_PERIOD	(1001/60000.0)

You can find these defines in C:/Kernel/KernelA.HH.Z.

Without this tweak there is a bit of mouse lag that can be quite annoying if you're trying out TempleOS for the first time. It's not that bad once you get used to it. But I'm definitely not going back.

Custom Colours

TempleOS already has a mechanism for distinct colour palettes. As seen in C:/Adam/Gr/GrPalette.HC.Z. However it seems that the expectation of actually swapping palettes falls on each individual program/task. For a system wide palette swap, you can add your own palettes into GrPalette.HC and give them a corresponding Set function and then replace a couple of lines in the function GrInit2 in C:/Adam/Gr/GrInitB.HC.Z.

//In GrPalette.HC.Z
CBGR48 gr_palette_dark[COLORS_NUM] = {
0xC1C1C1C1C1C1,0x55555555DCDC,0x5555DCDC5555,0x5555DCDCDCDC,
0xDCDC55555555,0xDCDC5555DCDC,0xFFFF9999AAAA,0xAAAAAAAAAAAA,
0x555555555555,0x55555555FFFF,0x5555FFFF5555,0x5555FFFFFFFF,
0xFFFF55555555,0xFFFF5555FFFF,0xFFFFFFFF5555,0x2A2A2A2A2A2A};

public U0 PaletteSetDark()
{
  GrPaletteSet(gr_palette_dark);
}
//In GrInitB.HC.Z
U0 Gr2Init2()
{
  //...
  PaletteSetDark;
  fp_set_std_palette=&PaletteSetDark;
  //...

Removing the call to PaletteSetStd and replacing it with your own seems like the only real way to get your palette to persist.

Another thing to note is that here my palette was specified as an array literal, mostly to match the style of the palettes that are already in that file. But it maybe more readable to first declare the palette array and then fill in each value one by one.

  CBGR48 gr_palette_dark[COLORS_NUM];
  gr_palette_dark[BLACK]	= 0xC1C1C1C1C1C1;
  gr_palette_dark[BLUE]		= 0x55555555DCDC;
  //...

A Couple of Colour Helper Functions

Here's a couple of colour related functions I had laying around in different files. PrintColours is useful for testing custom palettes. The GrPaletteInvert function is less useful, but it did help me test some stuff early on without having to write a completely new palette.

U0 PrintColours() {
  "$BLACK$black $BLUE$blue $CYAN$cyan $RED$red $PURPLE$purple $BROWN$brown$FG$\n";
  "$LTGRAY$ltgray $DKGRAY$dkgray$FG$\n";
  "$LTBLUE$ltblue $LTGREEN$ltgreen $LTCYAN$ltcyan $LTRED$ltred $LTPURPLE$ltpurple$FG\n"
  "$YELLOW$yellow $WHITE$white $FG$\n";
}

CBGR48 GrPaletteInvert(CBGR48 *src_palette) {
  CBGR48 invert[COLORS_NUM];
  I64 i;
  for(i = 0; i< COLORS_NUM; i++) {
    invert[i] = ~src_palette[i];
  }
  return invert;
}

More to Come Maybe?

I have more tips and tweaks I could share but documenting just these two was actually pretty involved. I was quite rusty with some of the details here, as it's been a little while since I implemented the colour stuff in particular.

But I do enjoy using TempleOS and I could certainly write a lot more about it. That being said I keep intending to write short posts but for some reason that doesn't seem to be happening.