Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor palette IO and storage #545

Merged
merged 15 commits into from
Sep 16, 2023

Conversation

lahm86
Copy link
Collaborator

@lahm86 lahm86 commented Sep 12, 2023

This continues the level IO refactoring and conversion of arrays into lists. The palettes and lightmaps are dealt with here (applies only to TR1-3).

Part of #507 and part of #468.

@lahm86 lahm86 added this to the 1.8.0 milestone Sep 12, 2023
@lahm86 lahm86 self-assigned this Sep 12, 2023
Write(colour.Blue);
Write(colour.Unused);
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we create an override Write(TRColour4 colour)?

Red = ReadByte(),
Green = ReadByte(),
Blue = ReadByte(),
Unused = ReadByte()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it really unused, or is it alpha? If it's unused maybe it's best to convert it to Colour3 and then write dummy values back?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unused in the original TR2 and I'm fairly sure it's the same for TR3. But you are right, TR2Main treats it as the alpha channel, so I think renaming it is a good idea as it makes sense that this should be its purpose.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed now to Alpha. I've also fixed a previous hack where we were keeping track of imported colours using the Unused property. There is now a proper tracker class for 16-bit colour import, which will also quantize if the palette runs out of space - very unlikely in TR2/3, but it's good practice.

@lahm86
Copy link
Collaborator Author

lahm86 commented Sep 13, 2023

I've simplified the palette16 tracker as it felt overly complicated for what it does. Best to do it now while it's fresh. It now makes a queue of free indices and these are then allocated to imported colours as necessary. It no longer assumes the colours are ordered by usage and so will accept gaps (not that it occurs in OG levels, but best not to assume). I also standardised the names between it and the palette8 control class, and shared out the method to find the nearest colour.
Some other minor tidying up - all in the latest commit.

@lahm86 lahm86 requested a review from rr- September 13, 2023 19:13
}

return colIndex;
}
Copy link

@rr- rr- Sep 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could change this to use more LINQ?

var indexed = palette.Select((paletteColour, index) => new {
    Index = index,
    Delta = Math.Sqrt(
        Math.Pow(colour.R - paletteColour.R, 2) +
        Math.Pow(colour.G - paletteColour.G, 2) +
        Math.Pow(colour.B - paletteColour.B, 2)
    ),
});

return indexed.Min(item => item.Delta).Index;

Also, it's unnecessary to call Math.Sqrt here to get the accurate Euclidean distance – for the purpose of determining the closest point, comparing the squared distances is sufficient and will yield the same result.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Good point about Math.Sqrt - some unnecessary calculations there :) Updated now with LINQ - just had to ensure we skip over index 0 for TR1, so we honour the passed in start index.

{
int multiplier = TRConsts.Palette8Multiplier;
return Color.FromArgb(c.Red * multiplier, c.Green * multiplier, c.Blue * multiplier);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is only used by TR1, I think it's worth highlighting it somehow with function names.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense - now renamed. I'm thinking we should only have one colour class eventually and have the IO handle this complexity - so multiplied out on read and divided on write for TR1. But I'll wait until we do more with TR3/4/5 lights as they use colours in different formats. That way we can manipulate colours as we please and the complexity is left until writing back.

It would also need updates to the custom model exports we use for cross-level enemies, so I think handling it later will be best.

@lahm86 lahm86 requested a review from rr- September 15, 2023 20:36
@@ -139,7 +124,7 @@ private static void ReindexMeshTextures(TRMesh[] meshes, Dictionary<int, int> in

private static ushort ReindexTexture(ushort value, Dictionary<int, int> indexMap, bool has16Bit)
{
int p16 = value;;
int p16 = value;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oo

@lahm86 lahm86 merged commit 80786dc into LostArtefacts:master Sep 16, 2023
2 checks passed
@lahm86 lahm86 deleted the issue-507-levelio-palette branch September 16, 2023 09:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants