This page contains fixes for various issues with the Klingon Academy game on new versions of Windows OS.

Multithreading crash fix
Resolution enabler
DirectInput crash fix
Rendering fix

Multithreading crash fix

Background

Sometimes the game crashes with Access violation error because its memory gets corrupted. This is caused by use of the no-serialize heap. This heap type assumes that it will be never accessed by more than one thread. Problem is that some callbacks from system functions are run in separate threads. This breaks that assumption. The result is a heap corruption. The fix removes the HEAP_NO_SERIALIZE flag from call to HeapCreate. For this to work properly, the game must not use its own heap implementation for small blocks. The small block heap is disabled on Windows 2000+ unless you run the executable in compatibility mode for earlier OS. If you run the game in Windows 95 or 98 compatibility mode, the fix does not work properly!.

How to apply automatically

The fix assumes that 1.02 patch (US, UK or German) is already applied.
  1. Download the patcher
  2. Unpack it to game directory where the ka.exe file resides
  3. Run the extracted ka_patcher.exe file.
If you plan to use the AI training variant kaai.exe, here is a patcher for it.

How to apply manually

The fix assumes that 1.02 patch (US, UK or German) is already applied. You need to open the ka.exe file in any hexadecimal editor and apply the changes mentioned bellow. The changes are described in following format:

offset: old_value new_value

Where the offset is offset from start of the file. At this offset is a single byte which should be changed. The old_value is value which should be there if you are at correct position in correct version of the ka.exe file. The new_value is value to which you should change the old value.

0030F1AB: 0F 90
0030F1AC: 94 90
0030F1AD: C0 90


If you are unsure how to do this change, there is a description how to do it with the free PSPad editor. Remember to back-up you original file so you can revert to it if you do something incorrectly.
  1. Open the file in the PSPad. The program should open in the hexadecimal mode
  2. Press Ctrl+G or select "Goto Line" from the Search menu.
  3. Ensure that the "From file beginning" choice is selected.
  4. Enter $0030F1AB into the "Bytes" field
  5. Starting from the cursor position you should see following: 0F 94C0 50FF. If that is not true, you are in incorrect version of file or you did something wrong in the previous steps so do NOT continue with the editing and try again from the beginning.
  6. Ensure that the overwrite mode is selected (visible in the status bar at the bottom of the window)
  7. Type 909090
  8. The result should now look like: 90 9090 50FF
  9. Save the file
The manual change for kaai.exe is:

0030F4CB: 0F 90
0030F4CC: 94 90
0030F4CD: C0 90

Resolution enabler

The resolution selection window in the standard launcher presents only limited number of resolutions. This patch disables the check so all resolutions enumerated on the system are available.

How to apply automatically

  1. Download the patcher
  2. Unpack it to game directory where the kalaunch.exe file resides
  3. Run the extracted kalaunch_patcher.exe file.

How to apply manually

Apply following changes to kalaunch.exe. Similar to the manual use of the multithreading patch.

000012CA: 75 90
000012CB: 1D 90
000012D2: 0F E9
000012D3: 84 85
000012D4: 84 00

DirectInput crash fix

Background

The Microsoft provided dinput.dll can in some cases cause memory corruption by writing after end of the allocated memory when the game is using EnumDevices to enumerate input devices. This happens because it incorrectly parses a HID information from some devices (e.g. Stream Deck) and attempts to initialize information for more axes than it allocated memory for.

In normal situation the issue causes semi random crashes when launching the game depending on what happens to be in the corrupted memory. When running with heap usage verification enabled, it will appear as crash in _CHid_InitAxisClass@16

The KA triggers this issue because it does not enable any device type filter when looking for joystick so the function will attempt to process all HID devices. The 1.30+ wrapper works around it by internally redirecting game's DirectInput enumeration and forces use of DIDEVTYPE_JOYSTICK filter. If necessary, this behavior can be disabled using D3DEMU_NO_DIRECT_INPUT_REDIRECT.

Rendering fix & improvements

The game has some graphical issues on new OS and GPUs. The most annoying one are white flashes in the background during movement. Another problem is absence of dithering on latest cards which makes the limitations of the 16bit color mode even more noticeable. I made a wrapper which translates game calls to the DX9 to fix the first issue. It also converts part of the rendering to 24bit colors to reduce the second issue (the textures are still 16 bit so additional dithering would still help), generates mipmaps and forces the textures to use trilinear filtering.

To use it, extract the file into the directory containing the ka.exe file. To remove it, delete the extracted ddraw.dll file. If you have any feedback, you can contact me at jiridvorak at centrum dot cz

Few screenshots of the improved rendering (click image for full scale version).
Klingon Academy 24bit rendering of beta ceti background Klingon Academy 24bit rendering of corona Klingon Academy 24bit rendering of nebula Klingon Academy mipmapping on ships

Known limitations

Configuration

The wrapper provides limited configuration options to work around issues on various systems or to trade output quality for speed. The configuration is done by creating environmental variables with specific name and any value unless specified otherwise.

Following variables are available:
Configuration you might want to maximize depending on your HW
D3DEMU_ANISOTROPYThe value must be number greater than or equal to 1 specifying quality of the filtering (1 - minimal). Alternatively a max might be used to indicate maximal supported quality. Quality values above the supported range are clamped to nearest valid value.
D3DEMU_MSAA_QUALITYThe value must be number greater than or equal to 1 specifying quality of the anti-aliasing. Alternatively a max might be used to indicate maximal supported quality. Quality values above the supported range are clamped to nearest valid value.
Configuration you might want to try
D3DEMU_NO_CPU_STARFIELDDisables CPU drawn dots in the starfield for significant performance gain.
D3DEMU_NO_LOCKABLE_ZDisables emulation of depth buffer reads. Increases speed and might fix compatibility issues with SLI solutions. Enabled automatically on ATI cards. No noticeable visual effect
D3DEMU_UI_30FPSAllows the UI to be run on 30 fps instead of the default 16. Causes UI stalls on lower end HW or when Fraps video recording is active.
D3DEMU_FORCE_BLACK_ALPHAImproves color consistency between surfaces with light sources (windows/impulse/warp) and surfaces without them.
D3DEMU_3D_FPS_LIMITSpecifies FPS limit to use for 3D game scene. Might improve game stability.
D3DEMU_UI_KEEP_ASPECT_RATIOForces the UI to be shown in the correct 4:3 aspect ratio on widescreen monitors. Note that 3D images on some control stations will have incorrect aspect ratio in this mode.
D3DEMU_VIDEO_KEEP_ASPECT_RATIOAttempts to detect KA video and show it in the correct 4:3 aspect ratio in fullscreen mode on widescreen monitors. Video might be vertically cropped on ultra-wide monitors.
Configuration for special uses
D3DEMU_3D_VISIONEnables support for Nvidia 3D Vision for KA (no SFA). As the game is old, there are few glitches - the PIP image is broken and the target reticle is drawn at the screen level. D3DEMU_NO_CPU_STARFIELD should be used
D3DEMU_KA_LOGReactivates remnants of the KA internal log and redirects its to wrapper's log.
D3DEMU_LOG_FLUSHFlushes the log after each output to ensure that it contains all the data if the game crashes for some reason.
Compatibility workarounds
D3DEMU_NO_VISTADisables use of extended DirectX interfaces on Vista.
D3DEMU_NO_HW_PROCESSINGSwitches between HW and SW vertex processing.
D3DEMU_NO_BUFFERSDisables use of vertex and index buffers.
D3DEMU_NO_HW_COLOR_CONVERSIONDisables GPU based color conversion for render targets.
D3DEMU_NO_COMPOSITION_COMPAREDisables check for changes in composition surface.
D3DEMU_NO_TIMERDisables timer based screen refreshes in the UI mode.
D3DEMU_NO_TIME_REDIRECTDisables redirection of GetTickCount to timeGetTime.
D3DEMU_NO_DIRECT_INPUT_REDIRECTDisables DirectInput redirection.
D3DEMU_NO_JOY_INDEX_REDIRECTDisables remapping of device indices Multimedia Joystick functions.
D3DEMU_MAX_BUSY_WAITMaximal duration of busy wait while applying framerate limit, defaults to 4 ms.
D3DEMU_IGNORE_KA_EXE_CHECKApplies KA specific patches regardless of name of the executable.
Creation of environment variables on English versions of Vista+
Use the control panel to search for "environment" keyword. In Vista it finds entry "Edit environment variables for your account". Use it to add new user variable with the desired name and any value.
Compilation from source code
To directly compile the source code you need the Microsoft Visual Studio 2008 (otherwise you might have to update the project for your environment) and DirectX SDK for DX versions 7 and 9.

Download

Version 1.32 (28.3.2023) - Stable.
Source code

History

Version 1.31 (27.3.2023) - Stable.
Source code
Version 1.30 (27.3.2023) - Stable.
Source code
Version 1.29 (20.8.2022) - Stable.
Source code
Version 1.28 (10.11.2021) - Stable.
Source code
Version 1.27 (10.11.2021) - Stable.
Source code
Version 1.26 (10.11.2021) - Stable.
Source code
Version 1.25 (10.11.2021) - Stable.
Source code
Version 1.24 (8.11.2021) - Stable.
Source code
Version 1.23 (8.11.2021) - Stable.
Source code
Version 1.22 (20.3.2015) - Stable.
Source code
Version 1.21 (19.8.2014) - Experimental.
Source code
Version 1.19 (21.3.2011) - Stable.
Source code
Version 1.20 (9.4.2011) - Experimental.
Source code
Version 1.18 (20.3.2011) - Experimental.
Source code
Version 1.17 (24.2.2011) - Stable.
Source code
Version 1.16 (23.2.2011) - Experimental.
Source code
Version 1.15 (19.2.2011) - Experimental.
Source code
Version 1.14 (14.2.2011) - Experimental.
Source code
Version 1.13 (6.2.2011) - Stable
Version 1.12 (5.2.2011) - Stable
Version 1.11 (30.1.2011) - Stable
Version 1.10 (29.1.2011) - Experimental, might contain new bugs
Version 1.09 (28.1.2011) - Experimental, might contain new bugs
Version 1.08 (27.1.2011) - Experimental, might contain new bugs
Version 1.07 (26.1.2011) - Experimental, might contain new bugs
Version 1.06 (23.1.2011) - Experimental, might contain new bugs
Version 1.05 (23.1.2011) - Experimental, might contain new bugs
Version 1.04 (22.1.2011) - Stable
Version 1.03 (20.1.2011)
Version 1.02 (20.1.2011)
Version 1.01 (15.1.2011)
Version 1.00 (27.12.2010)
Version 0.07 (24.12.2010)
Version 0.06 (23.12.2010)
Version 0.05 (23.12.2010)
Version 0.04
Version 0.03
Version 0.02