Tuesday, 15 May 2018

Checking for models

Just as a quick diversion from work I thought I'd look at the .naf files again and see if there was any way to get the models out.
The only real way to do this without knowing the format is to use process monitor from sysinternals to track the read access to the file and then dump it out to be processed.

So we end up with this kind of file where we can see the offsets that are being read from the file and the lengths that are being read. In this way we can work out the things like reads that are lengths of what to read next.


 So then writing some code to parse this file into something useful and look for these length values we end up with output like this.


The big lengths are what we are interested in here and you can see for example a length of 236,900 and 2 reads before it a potential length value of 11,845. If you divide 236,900 by 11,845 you get 20 exactly which suggests that this is 20 byte values repeated 11,845 times. 20 bytes would be 5 lots of 4 byte values. This could potentially be vertices and texture coordinates.

The 42 then 1 then 349680 are the dds files and you can see them increment as they go along.

Texture tool chain

Just a quick update to include a page for the texture roundtrip tool chain here: texture toolchain

Saturday, 21 April 2018

1.7 with the fps fix

I've released version 1.7 which includes the GOG 60 FPS fix which should fix most of the script timings crashes that people are experiencing.
I've tried to work through recreating these timing issues to fix the scripts but it's REALLY hard to work out where the problem lies with most of them so this is most likely the best fix.
You can download version 1.7 here.

More details on the DCoTEPatch page.

Saturday, 6 January 2018

The Hanging Woman bug

So I've taken a break from getting a 100% binary correct recompile as it's proving difficult!

Instead I thought I'd see if I can use what I have so far to fix some of the know bugs with the game within the game scripts so that they would work with all versions including the Steam one.

Somebody posted a list up here on steam so starting with the first one:

The Hanging Lady
This is a problem where you enter a room and there is a shock piece where your controls are frozen, your view is snap focused on the shock piece with some sound effects and then your controls are unfrozen.
The problem is that for people whose frame rates are higher than 60 this part crashes.
So I looked at the code for this that the decompiler had produced:

nVar767 = D_PlaySoundPositional("sound\sfx\01132.wav", ptVar763, 1.0, 900.0, 0);
D_SetGlobalInt("Hanging_Woman_Handle", nVar767);

nVar768 = D_GetInsanityShockTriggered("COURIER_HUNG_WOMAN_SHOCK");
if (nVar768 == 0)
{
  nVar768 = D_GetGlobalInt("Shock_Played");
  if (nVar768 == 0)
  {
    D_PlayerLockMove();
    D_EnableInsanityShock("COURIER_HUNG_WOMAN_SHOCK", 1);
    D_PlayerWatchObject("*REMOVEINSTATIC_BGANIM_HANGING", 1, "WatchRateVeryResponsive");
    D_EnableVisibilityTrigger("HOLY_SHIT", 0);
    D_SetGlobalInt("Shock_Played", 1);
    Wait(3.0);
    PlayerSayWithoutSuspend(4167, 1);
    D_PlayerUnlock();
    D_PlayerReleaseWatch();
  }
}
>
First it plays a positional sound and stores a handle to that sound so that it can later stop the sound from playing.
Next it checks if the shock has already played and if not then goes about playing the shock.
In the shock the player controls are locked out, the player is forced to watch the shock object, there is a pause of 3 seconds then the player controls and forced watch is released.
Within this some flags are set that are later going to be checked again to see if the shock has already been played.

Now my guess was that this was happening too fast when the fps was higher than 60 and that the handles and flags being set were being run multiple times at the same time.
The scripting engine handles this kind of problem by using BeginSafeBlock() and EndSafeBlock() to ensure that only one script is in this section at a time.

So this should fix it:

BeginSafeBlock();

nVar767 = D_PlaySoundPositional("sound\sfx\01132.wav", ptVar763, 1.0, 900.0, 0);
D_SetGlobalInt("Hanging_Woman_Handle", nVar767);

nVar768 = D_GetInsanityShockTriggered("COURIER_HUNG_WOMAN_SHOCK");
if (nVar768 == 0)
{
  nVar768 = D_GetGlobalInt("Shock_Played");
  if (nVar768 == 0)
  {
    D_PlayerLockMove();
    D_EnableInsanityShock("COURIER_HUNG_WOMAN_SHOCK", 1);
    D_PlayerWatchObject("*REMOVEINSTATIC_BGANIM_HANGING", 1, "WatchRateVeryResponsive");
    D_EnableVisibilityTrigger("HOLY_SHIT", 0);
    D_SetGlobalInt("Shock_Played", 1);
    Wait(3.0);
    PlayerSayWithoutSuspend(4167, 1);
    D_PlayerUnlock();
    D_PlayerReleaseWatch();
  }
}

EndSafeBlock();

And after testing, with help from a program called Special K, it does indeed fix the problem!

Will add this fix into the patcher when I get the chance :)