Version 1.2. Sanity checks, support for TIMAGE/SIMAGE of 0x5, 0x7 types.

This commit is contained in:
lprot 2011-12-12 02:13:58 +00:00
parent e72cbeae9e
commit f50189794c
7 changed files with 153 additions and 38 deletions

View file

@ -34,8 +34,8 @@ begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.Title := FormXBEExplorer.Caption;
Application.CreateForm(TfrmExploreFileSystem, frmExploreFileSystem);
Application.CreateForm(TFormXBEExplorer, FormXBEExplorer);
Application.CreateForm(TfrmExploreFileSystem, frmExploreFileSystem);
if ParamCount > 0 then
if FileExists(ParamStr(1)) then
FormXBEExplorer.OpenFile(ParamStr(1));

View file

@ -56,8 +56,6 @@ object frmExploreFileSystem: TfrmExploreFileSystem
Width = 441
Height = 393
Anchors = [akLeft, akTop, akRight, akBottom]
Lines.Strings = (
'Memo1')
TabOrder = 2
end
object ComboBox1: TComboBox

View file

@ -2,7 +2,7 @@ object FormXBEExplorer: TFormXBEExplorer
Left = 0
Top = 0
Caption = 'XBE Explorer'
ClientHeight = 788
ClientHeight = 612
ClientWidth = 836
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
@ -16,44 +16,49 @@ object FormXBEExplorer: TFormXBEExplorer
TextHeight = 13
object Splitter1: TSplitter
Left = 219
Top = 25
Height = 763
Top = 23
Height = 589
ExplicitLeft = 424
ExplicitTop = 376
ExplicitHeight = 100
end
object PageControl: TPageControl
Left = 222
Top = 25
Top = 23
Width = 614
Height = 763
Height = 589
Align = alClient
TabOrder = 0
ExplicitTop = 25
ExplicitHeight = 701
end
object ActionMainMenuBar: TActionMainMenuBar
Left = 0
Top = 0
Width = 836
Height = 25
Height = 23
UseSystemFont = False
ActionManager = ActionManager
ColorMap.HighlightColor = clWhite
ColorMap.HighlightColor = 15660791
ColorMap.BtnSelectedColor = clBtnFace
ColorMap.UnusedColor = clWhite
ColorMap.UnusedColor = 15660791
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = 'Segoe UI'
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
Spacing = 0
ExplicitHeight = 25
end
object Panel1: TPanel
Left = 0
Top = 25
Top = 23
Width = 219
Height = 763
Height = 589
Align = alLeft
TabOrder = 2
ExplicitTop = 25
ExplicitHeight = 701
object Splitter2: TSplitter
Left = 1
Top = 1
@ -80,10 +85,11 @@ object FormXBEExplorer: TFormXBEExplorer
Left = 1
Top = 326
Width = 217
Height = 436
Height = 262
Align = alClient
Caption = 'Panel2'
TabOrder = 1
ExplicitHeight = 374
object edt_SymbolFilter: TEdit
Left = 1
Top = 1
@ -97,7 +103,7 @@ object FormXBEExplorer: TFormXBEExplorer
Left = 1
Top = 22
Width = 215
Height = 413
Height = 239
Align = alClient
Columns = <
item
@ -115,6 +121,7 @@ object FormXBEExplorer: TFormXBEExplorer
ViewStyle = vsReport
OnColumnClick = lst_DissambledFunctionsColumnClick
OnDblClick = lst_DissambledFunctionsDblClick
ExplicitHeight = 351
end
end
end
@ -146,6 +153,7 @@ object FormXBEExplorer: TFormXBEExplorer
end
object Extra1: TMenuItem
Caption = 'Extra'
Enabled = False
object ExploreFileSystem1: TMenuItem
Caption = 'Explore Filesystem...'
OnClick = ExploreFileSystem1Click

View file

@ -211,6 +211,7 @@ end;
procedure TFormXBEExplorer.actCloseExecute(Sender: TObject);
begin
CloseFile;
Extra1.Enabled := False;
end;
procedure TFormXBEExplorer.actSaveAsUpdate(Sender: TObject);
@ -241,7 +242,7 @@ end;
procedure TFormXBEExplorer.About1Click(Sender: TObject);
begin
TaskMessageDlg('About ' + Application.Title,
Application.Title + ' version ' + _XBE_EXPLORER_VERSION + ' © 2010, PatrickvL. Released under GPL3.'#13#13 +
Application.Title + ' version ' + _XBE_EXPLORER_VERSION + ' © 2011, PatrickvL. Released under GPL3.'#13#13 +
Application.Title + ' is part of Dxbx - the Delphi Xbox1 emulator.'#13#13 +
'Website : http://sourceforge.net/projects/dxbx/',
mtInformation, [mbOK], 0);
@ -963,6 +964,12 @@ begin // OpenFile
CloseFile;
MyXBE := TXbe.Create(aFilePath);
if MyXBE.FisValid = False then
begin
MyXBE:=nil;
FormXBEExplorer.Extra1.Enabled := False;
Exit; // wrong magic etc
end;
FXBEFileName := ExtractFileName(aFilePath);
if not LoadSymbols and FileExists('Dxbx.exe') then
@ -1038,7 +1045,7 @@ begin // OpenFile
end;
TreeView1.Selected := Node0;
FormXBEExplorer.Extra1.Enabled := True;
Result := True;
end; // OpenFile

View file

@ -49,7 +49,7 @@ const
// Application Versions
_DXBX_VERSION = '0.6 ' + {$IFDEF DEBUG}'Debug'{$ELSE}'Release'{$ENDIF};
_XDK_TRACKER_VERSION = '2.1';
_XBE_EXPLORER_VERSION = '1.1';
_XBE_EXPLORER_VERSION = '1.2';
// Dialog Filters
DIALOG_FILTER_TEXT = 'Text Documents (*.txt)|*.txt';

View file

@ -36,8 +36,9 @@ uses
uTypes;
const // instead of using uEmuD3D8Types :
X_D3DFMT_A8R8G8B8 = $06; // 6, Swizzled
// X_D3DFMT_X8R8G8B8 = $07; // 7, Swizzled
X_D3DFMT_R5G6B5 = $05; // Swizzled 16bit ppx
X_D3DFMT_A8R8G8B8 = $06; // Swizzled 32bit ppx
X_D3DFMT_X8R8G8B8 = $07; // Swizzled 32bit ppx
X_D3DFMT_P8 = $0B; // 11, Swizzled, 8-bit Palletized
X_D3DFMT_DXT1 = $0C; // 12, Compressed, opaque/one-bit alpha
X_D3DFMT_DXT2 = $0E;
@ -243,7 +244,9 @@ type
function ReadS3TCFormatIntoBitmap(const aFormat: Byte; const aData: PBytes; const aDataSize: Cardinal; const aOutput: PRGB32Scanlines): Boolean;
function ReadSwizzledFormatIntoBitmap(const aFormat: Byte; const aData: PBytes; const aDataSize: Cardinal; const aOutput: PRGB32Scanlines): Boolean;
function ReadSwizzled16bitFormatIntoBitmap(const aFormat: Byte; const aData: PBytes; const aDataSize: Cardinal; const aOutput: PRGB16Scanlines): Boolean;
function ReadD3DTextureFormatIntoBitmap(const aFormat: Byte; const aData: PBytes; const aDataSize: Cardinal; const aOutput: PRGB32Scanlines): Boolean;
function ReadD3D16bitTextureFormatIntoBitmap(const aFormat: Byte; const aData: PBytes; const aDataSize: Cardinal; const aOutput: PRGB16Scanlines): Boolean;
function GetDxbxBasePath: string;
function SymbolCacheFolder: string;
@ -1274,7 +1277,77 @@ begin
Result := Length(FScanlines);
end;
//
// Unswizzle a texture. (Only works for 32bit, with power of 2 width and height.)
// Code is loosly based on XBMC guilib\DirectXGraphics.cpp
// Delphi translation and speed improvements by PatrickvL
function ReadSwizzled16bitFormatIntoBitmap(
const aFormat: Byte;
const aData: PBytes;
const aDataSize: Cardinal;
const aOutput: PRGB16Scanlines): Boolean;
// Generic swizzle function, usable for both x and y dimensions.
// When passing x, Max should be 2*height, and Shift should be 0
// When passing y, Max should be width, and Shift should be 1
function _Swizzle(const Value, Max, Shift: Cardinal): Cardinal;
begin
if Value < Max then
Result := Value
else
Result := Value mod Max;
// The following is based on http://graphics.stanford.edu/~seander/bithacks.html#InterleaveBMN :
// --------------------------------11111111111111111111111111111111
Result := (Result or (Result shl 8)) and $00FF00FF; // 0000000000000000111111111111111100000000000000001111111111111111
Result := (Result or (Result shl 4)) and $0F0F0F0F; // 0000111100001111000011110000111100001111000011110000111100001111
Result := (Result or (Result shl 2)) and $33333333; // 0011001100110011001100110011001100110011001100110011001100110011
Result := (Result or (Result shl 1)) and $55555555; // 0101010101010101010101010101010101010101010101010101010101010101
Result := Result shl Shift; // y counts twice : 1010101010101010101010101010101010101010101010101010101010101010
if Value >= Max then
Inc(Result, (Value div Max) * Max * Max shr (1 - Shift)); // x halves this
end;
var
height, width: Cardinal;
xswizzle: array of Cardinal;
x, y, sy: Cardinal;
yscanline: PRGB16Array;
begin
// Sanity checks :
Result := (aFormat in [X_D3DFMT_R5G6B5])
and Assigned(aData)
and (aDataSize > 0)
and Assigned(aOutput)
and (aOutput.Height > 0)
and (aOutput.Width > 0);
if not Result then
Exit;
height := aOutput.Height;
width := aOutput.Width;
// Precalculate x-swizzle :
SetLength(xswizzle, width);
if width > 0 then // Dxbx addition, to prevent underflow
for x := 0 to width - 1 do
xswizzle[x] := _Swizzle(x, {Max=}(height * 2), {Shift=}0);
// Loop over all lines :
if height > 0 then // Dxbx addition, to prevent underflow
for y := 0 to height - 1 do
begin
// Calculate y-swizzle :
sy := _Swizzle(y, {Max=}width, {Shift=}1);
// Copy whole line in one go (using pre-calculated x-swizzle) :
yscanline := aOutput.Scanlines[y];
if width > 0 then // Dxbx addition, to prevent underflow
for x := 0 to width - 1 do
yscanline[x] := PRGB16Array(aData)[xswizzle[x] + sy];
end; // for y
end; // ReadSwizzled16bitFormatIntoBitmap
// Unswizzle a texture. (Only works for 32bit, with power of 2 width and height.)
// Code is loosly based on XBMC guilib\DirectXGraphics.cpp
@ -1315,7 +1388,7 @@ var
yscanline: PRGB32Array;
begin
// Sanity checks :
Result := (aFormat in [X_D3DFMT_A8R8G8B8])
Result := (aFormat in [X_D3DFMT_A8R8G8B8,X_D3DFMT_X8R8G8B8])
and Assigned(aData)
and (aDataSize > 0)
and Assigned(aOutput)
@ -1467,16 +1540,31 @@ begin
X_D3DFMT_DXT5:
// Read the compressed texture into the bitmap :
Result := ReadS3TCFormatIntoBitmap(aFormat, aData, aDataSize, aOutput);
X_D3DFMT_A8R8G8B8:
X_D3DFMT_A8R8G8B8,
X_D3DFMT_X8R8G8B8:
// Read the swizzled texture into the bitmap :
Result := ReadSwizzledFormatIntoBitmap(aFormat, aData, aDataSize, aOutput);
else
Result := False;
end;
end;
function ReadD3D16bitTextureFormatIntoBitmap(
const aFormat: Byte;
const aData: PBytes;
const aDataSize: Cardinal;
const aOutput: PRGB16Scanlines): Boolean;
begin
case aFormat of
X_D3DFMT_R5G6B5:
// Uncompressed texture :
Result := ReadSwizzled16bitFormatIntoBitmap(aFormat, aData, aDataSize, aOutput);
else
Result := False;
end;
end;
function GetDxbxBasePath: string;
begin
SetLength(Result, MAX_PATH);

View file

@ -55,12 +55,12 @@ type
private
MyFile: TMemoryStream;
FRawData: MathPtr;
FIsValid: boolean;
m_KernelLibraryVersion: XBE_LIBRARYVERSION;
m_XAPILibraryVersion: XBE_LIBRARYVERSION;
procedure ConstructorInit;
function GetFileSize: Int64;
public
FIsValid: boolean;
XbePath: string;
m_Header: XBEIMAGE_HEADER;
m_Certificate: XBE_CERTIFICATE;
@ -1089,7 +1089,8 @@ end;
function TXbe.ExportXPRToBitmap(XprImage: PXPR_IMAGE; aBitmap: TBitmap): Boolean;
var
Width, Height: Cardinal;
Scanlines: RGB32Scanlines;
Scanlines16: RGB16Scanlines;
Scanlines32: RGB32Scanlines;
begin
Result := False;
@ -1101,17 +1102,30 @@ begin
Height := 1 shl ((XprImage.hdr.Texture.Format and X_D3DFORMAT_VSIZE_MASK) shr X_D3DFORMAT_VSIZE_SHIFT);
// Prepare easy access to the bitmap data :
aBitmap.PixelFormat := pf32bit;
aBitmap.SetSize(Width, Height);
Scanlines.Initialize(aBitmap);
if (XprImage.hdr.Header.dwTotalSize - XprImage.hdr.Header.dwHeaderSize)/Width/Height = 2 then
begin // 16 bit per pixel textures
aBitmap.PixelFormat := pf16bit;
Scanlines16.Initialize(aBitmap);
// Read the texture into the bitmap :
Result := ReadD3DTextureFormatIntoBitmap(
{Format=}(XprImage.hdr.Texture.Format and X_D3DFORMAT_FORMAT_MASK) shr X_D3DFORMAT_FORMAT_SHIFT,
{Data=}PBytes(@(XprImage.pBits[0])),
{DataSize=}XprImage.hdr.Header.dwTotalSize - XprImage.hdr.Header.dwHeaderSize,
{Output=}@Scanlines);
// Read the texture into the 16bit bitmap :
Result := ReadD3D16bitTextureFormatIntoBitmap(
{Format=}(XprImage.hdr.Texture.Format and X_D3DFORMAT_FORMAT_MASK) shr X_D3DFORMAT_FORMAT_SHIFT,
{Data=}PBytes(@(XprImage.pBits[0])),
{DataSize=}XprImage.hdr.Header.dwTotalSize - XprImage.hdr.Header.dwHeaderSize,
{Output=}@Scanlines16);
end else
begin // 32 bit per pixel textures
aBitmap.PixelFormat := pf32bit;
Scanlines32.Initialize(aBitmap);
// Read the texture into the 32bit bitmap :
Result := ReadD3DTextureFormatIntoBitmap(
{Format=}(XprImage.hdr.Texture.Format and X_D3DFORMAT_FORMAT_MASK) shr X_D3DFORMAT_FORMAT_SHIFT,
{Data=}PBytes(@(XprImage.pBits[0])),
{DataSize=}XprImage.hdr.Header.dwTotalSize - XprImage.hdr.Header.dwHeaderSize,
{Output=}@Scanlines32);
end;
Exit;
end;