Skip to content

Commit

Permalink
{{SSE] "Safe" definition of save header that sould handle all current…
Browse files Browse the repository at this point in the history
…ly known formats

We can't simply test for SSE as saves from the original edition can be
used with the new one.
  • Loading branch information
Hugues92 authored and Sharlikran committed Oct 18, 2017
1 parent 0ff7ba0 commit 2d32ed8
Showing 1 changed file with 77 additions and 6 deletions.
83 changes: 77 additions & 6 deletions wbDefinitionsTES5Saves.pas
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,33 @@ procedure DefineTES5SavesA;

{ TES5saves }

function SaveVersionDecider(aMinimum: Integer; aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;
var
aType : Integer;
Element : IwbElement;
Container: IwbDataContainer;
begin
Result := 0;
if not Assigned(aElement) then Exit;
Element := aElement;
while Assigned(Element.Container) do
Element := Element.Container;

if Supports(Element, IwbContainer, Container) then begin
Element := Container.ElementByPath['Save File Header\Header\Version'];
if Assigned(Element) then begin
aType := Element.NativeValue;
if aType>aMinimum then
Result := 1;
end;
end;
end;

function SaveVersionGreaterThan11Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;
begin
Result := SaveVersionDecider(11, aBasePtr, aEndPtr, aElement);
end;

function SaveFormVersionDecider(aMinimum: Integer; aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;
var
aType : Integer;
Expand Down Expand Up @@ -407,8 +434,14 @@ function ScreenShotDataCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aEleme
var
Element : IwbElement;
Container: IwbDataContainer;
BitSize: Integer;
begin
Result := 0;
if 1 = SaveVersionGreaterThan11Decider(aBasePtr, aEndPtr, aElement) then
BitSize := 4
else
BitSize := 3;

if not Assigned(aElement) then Exit;
Element := aElement;
while Assigned(Element.Container) do
Expand All @@ -420,7 +453,7 @@ function ScreenShotDataCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aEleme
Result := Element.NativeValue;
Element := Container.ElementByPath['Save File Header\Header\Screenshot Height'];
if Assigned(Element) then begin
Result := 3 * Result * Element.NativeValue;
Result := BitSize * Result * Element.NativeValue;
end;
end;
end;
Expand Down Expand Up @@ -2005,6 +2038,27 @@ function ChangedFormExtraDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aEle
end;
end;

function SaveHeaderUnk3Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;
var
aType : Integer;
Element : IwbElement;
Container: IwbDataContainer;
begin
Result := 0;
if not Assigned(aElement) then Exit;
Element := aElement;
Element := Element.Container;

if Supports(Element, IwbContainer, Container) then begin
Element := Container.ElementByName['Unk3'];
if Assigned(Element) then begin
aType := Element.NativeValue;
if aType = -1 then
Result := 1;
end;
end;
end;

function ChangedFormDataCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;
var
Element : IwbElement;
Expand Down Expand Up @@ -5964,7 +6018,8 @@ procedure DefineTES5SavesS; // This is all based on current UESP, and HexDump,
wbFloat('Player LevelUp Experience'),
wbByteArray('Save Time', 8),
wbInteger('Screenshot Width', itU32),
wbInteger('Screenshot Height', itU32)
wbInteger('Screenshot Height', itU32),
wbUnion('', SaveVersionGreaterThan11Decider, [wbNull, wbInteger('Unknown', itU16)])
]);

wbFileLocationTable := wbStruct('File Location Table', [
Expand All @@ -5986,10 +6041,26 @@ procedure DefineTES5SavesS; // This is all based on current UESP, and HexDump,
,wbInteger('Header Size', itU32)
,wbHeader
,wbByteArray('Hidden: Screenshot Data', ScreenShotDataCounter)
,wbInteger('Form Version', itU8)
,wbInteger('PluginInfo Size', itU32)
,wbArray(wbFilePlugins, wbLenString('PluginName', 2), -4)
,wbFileLocationTable
,wbUnion('', SaveVersionGreaterThan11Decider, [wbInteger('Form Version', itU8),
wbStruct('Unknown', [
wbByteArray('Unknown', 8)
,wbByteArray('Unknown', 1)
,wbInteger('Unk3', itS8) // SSE ! with the 3 deviant saves I have, this works.
,wbByteArray('Unknown', 1)
,wbUnion('Unknown', SaveHeaderUnk3Decider, [ wbNull, wbInteger('Unknown', itU8) ])
])
])
,wbUnion('', SaveVersionGreaterThan11Decider, [
wbStruct('', [
wbInteger('PluginInfo Size', itU32)
,wbArray(wbFilePlugins, wbLenString('PluginName', 2), -4) // SSE ! There are non printable character where the plugin name should show.
,wbFileLocationTable
])
,wbByteArray('PluginInfo', -1) // SSE ! skip over the array of plugin names
])
// SSE ! There is most likely something before FileLocationTable or the file location table elements have changed
,wbByteArray('Unused', SkipCounter) // Lets you skip an arbitrary number of byte, Setable from CommandLine -bts:n
,wbArray('Remaining', WbByteArray('Unknown', wbBytesToGroup), DumpCounter) // Lets you dump an arbitrary number of quartet, Setable from CommandLine -btd:n
]);

wbSaveChapters := wbStruct('Save File Chapters', [
Expand Down

0 comments on commit 2d32ed8

Please sign in to comment.