|
ShrineFox
|
Sep 17 2015, 09:37 PM
Post #1
|
Webmaster
- Posts:
- 825
- Group:
- Webmaster
- Member
- #1
- Joined:
- Sep 16, 2015
- Programming Languages
- C#
- Country
- United States
|
Font Decompressor by RikuKH3

source code - Code:
-
program Project1;
{$WEAKLINKRTTI ON} {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
{$APPTYPE CONSOLE}
{$R *.res}
uses Windows, System.SysUtils, System.Classes;
{$SETPEFLAGS IMAGE_FILE_RELOCS_STRIPPED}
var s2,s4,v0, DictBlockPos, LastBlockPos, OutputWritePos, LongWord1: LongWord; Word1: Word; Byte1: Byte; MemoryStream1, MemoryStream2: TMemoryStream; begin try MemoryStream1:=TMemoryStream.Create; try MemoryStream2:=TMemoryStream.Create; try Writeln('Persona 3+4 font decompressor by RikuKH3'); Writeln('----------------------------------------'); if ParamCount<>1 then begin Writeln('Usage: p3fontdec.exe input_file'); exit end; if not (FileExists(ParamStr(1))) then begin Writeln('Cannot open file "'+ExpandFileName(ParamStr(1))+'". The system cannot find the file specified'); exit end; MemoryStream2.LoadFromFile(ParamStr(1)); MemoryStream2.Position:=$E; MemoryStream2.ReadBuffer(Word1,2); //total glyph count MemoryStream2.Position:=$20; MemoryStream1.CopyFrom(MemoryStream2,64); //4-byte-per-color palette MemoryStream2.ReadBuffer(LongWord1,4); //width table size MemoryStream2.Position:=LongWord1+Word1*4+112; MemoryStream2.ReadBuffer(LongWord1,4); //last block size
DictBlockPos:=MemoryStream2.Position+22; //$C5A LastBlockPos:=MemoryStream2.Size-LongWord1; //$1F88 v0:=DictBlockPos; s2:=0; OutputWritePos:=$40;
MemoryStream2.Position:=LastBlockPos; MemoryStream2.ReadBuffer(Word1,2); s4:=Word1+$10000; //this gives exactly 16 cycles until s4=$01 repeat //checks if number is even, if not adds +2 to position if Odd(s4) then MemoryStream2.Position:=v0+2 else MemoryStream2.Position:=v0; MemoryStream2.ReadBuffer(Word1,2); v0:=Word1*6+DictBlockPos; MemoryStream2.Position:=v0; MemoryStream2.ReadBuffer(Word1,2); if Word1=0 then begin MemoryStream2.Position:=v0+2; MemoryStream2.ReadBuffer(Byte1,1); MemoryStream1.Position:=OutputWritePos; MemoryStream1.WriteBuffer(Byte1,1); OutputWritePos:=OutputWritePos+1; v0:=DictBlockPos; end; s4:=s4 shr $01; //shifts bit right if s4=$01 then //this part reads next 2 compressed bytes begin s2:=s2+2; if s2+LastBlockPos>=MemoryStream2.Size-1 then break; //my dirty loop exit MemoryStream2.Position:=s2+LastBlockPos; MemoryStream2.ReadBuffer(Word1,2); s4:=Word1+$10000; end; until 1=2; finally MemoryStream2.Free end; MemoryStream1.SaveToFile(Copy(ExpandFileName(ParamStr(1)),1,Length(ExpandFileName(ParamStr(1)))-Length(ExtractFileExt(ExpandFileName(ParamStr(1)))))+'_dec.bin'); Writeln('"'+ExtractFileName(ParamStr(1))+'" processed succesfully!' ); finally MemoryStream1.Free end; except on E: Exception do Writeln(E.Message); end; end.
|