From 3b53c7c20d2e5feb761ea6895bd2a1cb92eee6b7 Mon Sep 17 00:00:00 2001 From: BoBo_Fett <93382571+JKBoBoFett@users.noreply.github.com> Date: Wed, 21 Dec 2022 06:07:00 -0500 Subject: [PATCH] Added 24 + 32 bit support --- BMP_IO.pas | 157 +++++++++++++++++++++++++++++------- BMParrays.pas | 64 ++++++++++----- EditMTS.dfm | 156 ++++++++++++++++++++++++++++++++++++ EditMTS.pas | 65 +++++++++++++++ EditMat.dfm | 26 ++++-- EditMat.pas | 200 ++++++++++++++++++++++++++++++++++++++++++---- GloabalVars.pas | 9 +++ MAIN.PAS | 179 +++++++++++++++++++++++++---------------- MAIN.dfm | Bin 10639 -> 10589 bytes MATImage.pas | 164 +++++++++++++++++++++++++++++++++---- Mat16.DPR | 20 +++-- Mat16.dproj | 42 ++-------- Mat16.dproj.local | 16 ++-- Mat16.dres | Bin 4740 -> 0 bytes Mat16.res | Bin 4768 -> 4768 bytes Util.pas | 28 ++++++- about_unit.dfm | Bin 74112 -> 74112 bytes gobform.dfm | Bin 1974 -> 1971 bytes gobform.pas | 53 ++---------- gobgoo.pas | 102 ++++++++++++++++++++++- 20 files changed, 1036 insertions(+), 245 deletions(-) create mode 100644 EditMTS.dfm create mode 100644 EditMTS.pas create mode 100644 GloabalVars.pas delete mode 100644 Mat16.dres diff --git a/BMP_IO.pas b/BMP_IO.pas index 8872575..25af964 100644 --- a/BMP_IO.pas +++ b/BMP_IO.pas @@ -124,6 +124,8 @@ procedure Save32bitA(ABitmap: TBitmap;Alpha:boolean; const AFileName: string); procedure Save16bitA1555BMP(ABitmap: TBitmap; const AFileName: string); function GetPaddedRowSize(bpp,width:integer):integer; procedure BMP_Save(Abitmap:Tbitmap; filename: string); +function BMPFMTtoStr(Format:TBMPFORMAT):string; +function Convert32bitTo16bit(bmp32:Tbitmap):Tbitmap; var inputBMPFormat:TBMPFORMAT; @@ -252,15 +254,17 @@ function BMP_Open(filename: string): Tbitmap; if (bmfmask.GreenMask = 2016) then // 16-bit 565 format begin rin_bitmap.PixelFormat := pf16bit; //allways define pf first + rin_bitmap.HandleType := bmDIB; rin_bitmap.Width := bminfo.Width; rin_bitmap.Height := bminfo.Height; formatgood := True; inputBMPFormat:=bf16bit565; end; - if (bmfmask.GreenMask = 240) then // 16-bit 4444 format + if (bmfmask.GreenMask = 240) or (bmfmask.GreenMask = 3840) then // 16-bit 4444 format begin rin_bitmap.PixelFormat := pf32bit; //VCL doesn't support display of 4444 so we'll convert to 32bit + rin_bitmap.HandleType := bmDIB; rin_bitmap.SetSize(bminfo.Width,bminfo.Height); formatgood := true; if hasAlpha then inputBMPFormat:=bf16bitA444 //can read alpha format in header since we are loading an externally created bitmap @@ -271,6 +275,7 @@ function BMP_Open(filename: string): Tbitmap; if (bminfo.Compression = BI_RGB) or (bmfmask.GreenMask = 992) then //BI_RGB 1555 doesn't have a fieldmask header begin rin_bitmap.PixelFormat := pf15bit; //allways define pf first + rin_bitmap.HandleType := bmDIB; rin_bitmap.Width := bminfo.Width; rin_bitmap.Height := bminfo.Height; formatgood := True; @@ -289,7 +294,7 @@ function BMP_Open(filename: string): Tbitmap; if (rin_bitmap.PixelFormat = pf32bit) and (bmfmask.GreenMask = 240) then begin - rin_bitmap.AlphaFormat:=afdefined; + rin_bitmap.AlphaFormat:=afIgnored; {setting as defined seems to cause pre multiplication after conversion} for j := rin_bitmap.Height - 1 downto 0 do begin inrow := rin_bitmap.ScanLine[j]; @@ -320,15 +325,16 @@ function BMP_Open(filename: string): Tbitmap; seek(f, bmhead.BitmapOffset); //warp to bitmap data rin_bitmap.PixelFormat := pf24bit; //allways define pf first + rin_bitmap.HandleType := bmDIB; rin_bitmap.Width := bminfo.Width; rin_bitmap.Height := bminfo.Height; formatgood := True; //FIX ME - + inputBMPFormat:=bf24bit; //read in bitmap for i := bminfo.Height - 1 downto 0 do BlockRead(f, rin_bitmap.Scanline[i]^, bminfo.Width * 3); - Result := rin_bitmap; + Result.Assign(rin_bitmap); CloseFile(f); end; // end of 24-bit @@ -349,9 +355,11 @@ function BMP_Open(filename: string): Tbitmap; seek(f, bmhead.BitmapOffset); //warp to bitmap data rin_bitmap.PixelFormat := pf32bit; //allways define pf first + rin_bitmap.HandleType := bmDIB; rin_bitmap.Width := bminfo.Width; rin_bitmap.Height := bminfo.Height; formatgood := True; //FIX ME + inputBMPFormat:=bf32bit; //read in bitmap if (bminfo.Compression = BI_RGB) or (bmfmask.GreenMask = $0000FF00) then @@ -386,29 +394,29 @@ function BMP_Open(filename: string): Tbitmap; - png := TPngImage.Create(); - - +// png := TPngImage.Create(); +// +// Result.Assign(rin_bitmap); CloseFile(f); - - png.Assign(rin_bitmap); - png.CreateAlpha; - - for J:=0 to rin_bitmap.Height - 1 do - begin - BMPInRow := rin_bitmap.ScanLine[J]; - RowAlpha := png.AlphaScanline[J]; - for i:=0 to rin_bitmap.Width - 1 do - RowAlpha[i] := BMPInRow[i].rgbReserved; - - - - - end; - - - png.SaveToFile('D:\TestBMP\Test32Save.png'); +// +// png.Assign(rin_bitmap); +// png.CreateAlpha; +// +// for J:=0 to rin_bitmap.Height - 1 do +// begin +// BMPInRow := rin_bitmap.ScanLine[J]; +// RowAlpha := png.AlphaScanline[J]; +// for i:=0 to rin_bitmap.Width - 1 do +// RowAlpha[i] := BMPInRow[i].rgbReserved; +// +// +// +// +// end; +// +// +// png.SaveToFile('D:\TestBMP\Test32Save.png'); // Save32bitA(Result,hasAlpha,'D:\TestBMP\Test32Save.bmp'); //Result.SaveToFile('D:\TestBMP\Test32Save.bmp'); end; // end of 32-bit @@ -765,6 +773,73 @@ procedure Save16bit565(ABitmap: TBitmap; const AFileName: string); end; +procedure Save16bit4444(ABitmap: TBitmap; const AFileName: string); +const + PixelCountMax = 65536; // 2048 MAX WIDTH +type + TRGBQuadArray = array[0..PixelCountMax - 1] of TRGBQuad; + pRGBQuadArray = ^TRGBQuadArray; +var + FS: TFileStream; + BFH: TBMPHeader; + BIH: TBMPInfo; + BIHEX:TBMPInfoV4ext; + y,w: Integer; + sl: PWordArray; + RGBQuadLineArray: pRGBQuadArray; + DestRGBA:tagRGBQuad; + Dest16bitPixel:word; +begin + FS := TFileStream.Create(AFileName, fmCreate); + try + + // Bitmap file header + FillChar(BFH, SizeOf(BFH), 0); + BFH.tag := $4D42; // BM + BFH.filesize := 2 * ABitmap.Width * ABitmap.Height + SizeOf(BFH) + SizeOf(BIH)+ SizeOf(BIHEX); + BFH.BitmapOffset := SizeOf(BFH) + SizeOf(BIH) + SizeOf(BIHEX); + FS.Write(BFH, SizeOf(BFH)); + + // Bitmap info header + FillChar(BIH, SizeOf(BIH), 0); + BIH.Size := SizeOf(BIH)+SizeOf(BIHEX); + BIH.Width := ABitmap.Width; + BIH.Height := ABitmap.Height; + BIH.Planes := 1; + BIH.BitsPerPixel := 16; + BIH.Compression := BI_BITFIELDS; + BIH.SizeOfBitmap := 2 * (ABitmap.Width * ABitmap.Height); + FillChar(BIHEX, SizeOf(BIHEX), 0); + BIHEX.RedMask:=$F000; + BIHEX.GreenMask:=$F00; + BIHEX.BlueMask:=$F0; + BIHEX.AlphaMask:=$F; + FS.Write(BIH, SizeOf(BIH)); + FS.Write(BIHEX, SizeOf(BIHEX)); + + // Pixels + for y := ABitmap.Height - 1 downto 0 do + begin + RGBQuadLineArray := ABitmap.ScanLine[y]; + for w := 0 to ABitmap.Width - 1 do + begin + DestRGBA.rgbRed:=RGBQuadLineArray[w].rgbRed shr 4; + DestRGBA.rgbGreen:=RGBQuadLineArray[w].rgbGreen shr 4; + DestRGBA.rgbBlue:=RGBQuadLineArray[w].rgbBlue shr 4; + DestRGBA.rgbReserved:=RGBQuadLineArray[w].rgbReserved shr 4; + + Dest16bitPixel:=DestRGBA.rgbRed shl 12 or DestRGBA.rgbGreen shl 8 or DestRGBA.rgbBlue shl 4 or DestRGBA.rgbReserved shl 0; + FS.Write(Dest16bitPixel, sizeof(word)); + end; + //FS.Write(sl^, 2 * ABitmap.Width); + end; + + finally + FS.Free; + end; + +end; + procedure Save32bitA(ABitmap: TBitmap;Alpha:boolean; const AFileName: string); var @@ -798,10 +873,13 @@ procedure Save32bitA(ABitmap: TBitmap;Alpha:boolean; const AFileName: string); FillChar(BIHEX, SizeOf(BIHEX), 0); BIHEX.AlphaMask:=$00000000; if Alpha then - BIHEX.AlphaMask:=$FF000000; + BIHEX.AlphaMask:=$FF000000; + // BIHEX.RedMask:= $000000FF; BIHEX.RedMask:= $00FF0000; BIHEX.GreenMask:=$0000FF00; BIHEX.BlueMask:= $000000FF; + //BIHEX.BlueMask:= $00FF0000; + BIHEX.CSType:= $73524742; FS.Write(BIH, SizeOf(BIH)); FS.Write(BIHEX, SizeOf(BIHEX)); @@ -845,14 +923,39 @@ procedure BMP_Save(Abitmap:Tbitmap; filename: string); Save16bit565(Abitmap, filename); end; + if BMPFormat = bf24bit then + begin + Abitmap.SaveToFile(filename); + end; + if BMPFormat = bf32bit then begin Save32bitA(Abitmap,true, filename); + //Save16bit4444(Abitmap, filename); {not tested} end; +end; +function BMPFMTtoStr(Format:TBMPFORMAT):string; +begin +//TBMPFormat = (bf8bit, bf16bitX1555, bf16bitA1555, bf16bitX444,bf16bitA444, bf16bit565, bf24bit, bf32bit, bfCustom); + case Format of + bf8bit: result:='bf8bit'; + bf16bitX1555: result:='bf16bitX1555'; + bf16bitA1555: result:='bf16bitA1555'; + bf16bitX444: result:='bf16bitX444'; + bf16bitA444: result:='bf16bitA444'; + bf16bit565: result:='bf16bit565'; + bf24bit: result:='bf24bit'; + bf32bit: result:='bf32bit'; + bfCustom: result:='bfCustom'; + end; +end; - +function Convert32bitTo16bit(bmp32:Tbitmap):Tbitmap; +begin end; + + end. diff --git a/BMParrays.pas b/BMParrays.pas index 39af2d4..9bb47da 100644 --- a/BMParrays.pas +++ b/BMParrays.pas @@ -1,7 +1,7 @@ unit BMParrays; //because imagelist use will remap pallete interface -uses Windows,Graphics, SysUtils, Classes,MATHeaders,ColorMap,CMPHeaders,util,System.IOUtils,Dialogs,BMP_IO; +uses Windows,Graphics, SysUtils, Classes,MATHeaders,ColorMap,CMPHeaders,util,System.IOUtils,Dialogs,BMP_IO,System.StrUtils; Type @@ -21,7 +21,7 @@ TBMPARRAY = class(TPersistent) procedure setformat(fmt:string); public - + name:Ansistring; isTransparent:Boolean; procedure ConvertBMPPal; procedure RemapArrayfromCMP(cmp: TCMP); @@ -211,6 +211,7 @@ function TBMPARRAY.GetCellColorIndex(Cellindex:Integer):Integer; inrow32: PRGBQuad; row16:PWordArray; j,i:integer; + begin BMPAlpha:=Tbitmap.create; BMPAlpha.Assign(CellBitmaps[index]); @@ -240,7 +241,6 @@ function TBMPARRAY.GetCellColorIndex(Cellindex:Integer):Integer; BMPAlpha.Free; end; - function TBMPARRAY.GetMip(Cellindex,Mipindex:Integer):Tbitmap; begin Result:=Tbitmap.create; @@ -312,7 +312,7 @@ destructor TBMPARRAY.Destroy; CMPData:=default(TCMPPal); - + name:=''; inherited; end; @@ -343,15 +343,17 @@ destructor TBMPARRAY.Destroy; Splitted: TArray<String>; tempBitmap:Tbitmap; begin - gpath := ExtractFilePath(filename); - tempBitmap:=Tbitmap.create; - AssignFile(Txt, filename); + + gpath := ExtractFilePath(filename); + AssignFile(Txt, filename); Reset(Txt); while not Eof(Txt) do begin Readln(Txt, s); Splitted := s.Split([':']); + if Splitted[0] = 'FILENAME' then + self.name:=trim(Splitted[1]); if Splitted[0] = 'FORMAT' then self.setformat(trim(Splitted[1])); if Splitted[0] = 'TRANSPARENT' then @@ -368,15 +370,19 @@ destructor TBMPARRAY.Destroy; Splitted := s.Split(['|']); if fileexists(gpath+Splitted[0]) then begin - tempBitmap.LoadFromFile(gpath+Splitted[0]); + //tempBitmap.LoadFromFile(gpath+Splitted[0]); + tempBitmap:=(BMP_Open(gpath+Splitted[0])); //function creates bmp self.AddCellFromBMP(tempBitmap); + //tempBitmap.Free; self.ConvertBMPPal; for K := 1 to length(Splitted)-1 do begin if fileexists(gpath+Splitted[K]) then begin - tempBitmap.LoadFromFile(gpath+Splitted[K]); + //tempBitmap.LoadFromFile(gpath+Splitted[K]); + tempBitmap:=(BMP_Open(gpath+Splitted[K])); //function creates bmp self.AddSubMipMapFromBMP(tempBitmap); + // tempBitmap.Free; end; end; end @@ -385,12 +391,10 @@ destructor TBMPARRAY.Destroy; end; end; - end; CloseFile(Txt); tempBitmap.Free; tempBitmap:=nil; - // Splitted := MyString.Split([':']); end; procedure TBMPARRAY.SaveMTS(filename: string); @@ -398,8 +402,15 @@ destructor TBMPARRAY.Destroy; i,j,k: integer; OutFile: textfile; savebitmap: Tbitmap; - mname,gpath,mpath: string; + mname,gpath,mpath: Ansistring; begin + {filename needs to be the mat filename} + if (UpperCase(ExtractFileExt(filename)) <> '.MAT') then + begin + raise Exception.Create('Save MTS wrong file type'); + end; + + AssignFile(OutFile, ChangeFileExt(filename, '.mat16s')); Rewrite(OutFile); @@ -416,7 +427,9 @@ destructor TBMPARRAY.Destroy; for J := 0 to self.GetCellCount - 1 do begin + //savebitmap:=Tbitmap.Create; savebitmap:=(self.GetCell(J)); + //savebitmap.Assign(self.GetCell(J)); mname := ExtractName(filename); mname := TPath.GetFileNameWithoutExtension(mname); mname := mname+'_Cell'+inttostr(j); @@ -425,11 +438,15 @@ destructor TBMPARRAY.Destroy; Write(OutFile,mname); -// if saveBitmap.PixelFormat = pf32bit then -// SaveTransparentBitmap(saveBitmap, mpath) //work around for saving Tbitmap with alpha -// -// else -// saveBitmap.SaveToFile(mpath); + if (UpperCase(ExtractFileExt(mpath)) <> '.BMP') then + begin + raise Exception.Create('Save MTS Cell wrong file type'); + end; + + if not ContainsText(mpath,'_Cell') then + begin + raise Exception.Create('Save MTS Cell wrong file type'); + end; BMP_Save(saveBitmap, mpath); @@ -441,6 +458,7 @@ destructor TBMPARRAY.Destroy; begin //savebitmap := Tbitmap.Create; savebitmap:=(self.GetMip(J,K)); + //savebitmap.Assign(self.GetCell(J)); mname := ExtractName(filename); mname := TPath.GetFileNameWithoutExtension(mname); mname := mname+'_Cell'+inttostr(j)+'_Mip'+inttostr(K); @@ -453,7 +471,17 @@ destructor TBMPARRAY.Destroy; // SaveTransparentBitmap(saveBitmap, mpath) //work around for saving Tbitmap with alpha // // else -// saveBitmap.SaveToFile(mpath); +// saveBitmap.SaveToFile(mpath); + if (UpperCase(ExtractFileExt(mpath)) <> '.BMP') then + begin + raise Exception.Create('Save MTS MIP wrong file type'); + end; + + if not ContainsText(mpath,'_Mip') then + begin + raise Exception.Create('Save MTS Cell wrong file type'); + end; + BMP_Save(saveBitmap, mpath); saveBitmap.Free; diff --git a/EditMTS.dfm b/EditMTS.dfm new file mode 100644 index 0000000..cf6d8f4 --- /dev/null +++ b/EditMTS.dfm @@ -0,0 +1,156 @@ +object EditMTSForm: TEditMTSForm + Left = 0 + Top = 0 + BorderIcons = [biSystemMenu] + BorderStyle = bsSingle + Caption = 'EditMTSForm' + ClientHeight = 334 + ClientWidth = 518 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -13 + Font.Name = 'Tahoma' + Font.Style = [] + OldCreateOrder = False + PixelsPerInch = 120 + TextHeight = 16 + object Label1: TLabel + Left = 224 + Top = 14 + Width = 80 + Height = 16 + Hint = 'mats can have up to 16 cells' + Caption = 'Cells (LOD 0):' + ParentShowHint = False + ShowHint = True + end + object Label2: TLabel + Left = 368 + Top = 14 + Width = 120 + Height = 16 + Hint = 'mats can have up to 3 mips for each cell' + Caption = 'MIP chain (LOD 1-3):' + ParentShowHint = False + ShowHint = True + end + object Label3: TLabel + Left = 8 + Top = 14 + Width = 75 + Height = 16 + Caption = 'Mat Preview:' + end + object CellsListBox: TListBox + Left = 224 + Top = 36 + Width = 113 + Height = 153 + TabOrder = 0 + end + object MipsListBox: TListBox + Left = 368 + Top = 36 + Width = 113 + Height = 153 + TabOrder = 1 + end + object Panel1: TPanel + Left = 8 + Top = 36 + Width = 128 + Height = 128 + BevelInner = bvLowered + TabOrder = 2 + object Image1: TImage + Left = 2 + Top = 2 + Width = 124 + Height = 124 + Align = alClient + Proportional = True + Stretch = True + ExplicitLeft = 0 + ExplicitTop = 28 + end + end + object OKButton: TButton + Left = 229 + Top = 283 + Width = 75 + Height = 25 + Caption = 'OK' + ModalResult = 1 + TabOrder = 3 + end + object Options: TGroupBox + Left = 10 + Top = 195 + Width = 503 + Height = 82 + Caption = 'Options' + TabOrder = 4 + object Label4: TLabel + Left = 14 + Top = 21 + Width = 134 + Height = 16 + Caption = 'Internal bitmap format:' + end + object MipRadioGroup: TRadioGroup + Left = 214 + Top = 23 + Width = 161 + Height = 46 + Caption = 'MIP maps to Auto-create' + Columns = 4 + ItemIndex = 0 + Items.Strings = ( + '0' + '1' + '2' + '3') + TabOrder = 0 + end + object AddCellButton: TButton + Left = 396 + Top = 28 + Width = 75 + Height = 25 + Hint = 'bmp must match internal format' + Caption = 'Add Cell' + ParentShowHint = False + ShowHint = True + TabOrder = 1 + end + object FormatComboBox: TComboBox + Left = 14 + Top = 43 + Width = 185 + Height = 24 + TabOrder = 2 + Text = 'Select Internal Format' + Items.Strings = ( + '8-bit ' + '8-bit Transparent' + '16-bit 565' + '16-bit 1555 Transparent' + '16-bit 4444 (custom engine)') + end + end + object LoadButton: TButton + Left = 83 + Top = 283 + Width = 75 + Height = 25 + Caption = 'load mts' + ModalResult = 1 + TabOrder = 5 + OnClick = LoadButtonClick + end + object OpenPic: TOpenPictureDialog + Left = 176 + Top = 112 + end +end diff --git a/EditMTS.pas b/EditMTS.pas new file mode 100644 index 0000000..3a33bf0 --- /dev/null +++ b/EditMTS.pas @@ -0,0 +1,65 @@ +unit EditMTS; + +interface + +uses + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, + Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtDlgs, Vcl.StdCtrls, Vcl.ExtCtrls; + +type + TEditMTSForm = class(TForm) + Label1: TLabel; + Label2: TLabel; + Label3: TLabel; + CellsListBox: TListBox; + MipsListBox: TListBox; + Panel1: TPanel; + Image1: TImage; + OKButton: TButton; + Options: TGroupBox; + Label4: TLabel; + MipRadioGroup: TRadioGroup; + AddCellButton: TButton; + FormatComboBox: TComboBox; + OpenPic: TOpenPictureDialog; + LoadButton: TButton; + procedure LoadButtonClick(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + end; + +var + EditMTSForm: TEditMTSForm; + +implementation + +{$R *.dfm} + +procedure TEditMTSForm.LoadButtonClick(Sender: TObject); +var + Txt: TextFile; + s,gpath:string; + Splitted: TArray<String>; +begin + OpenPic.Filter:='mat16 script|*.mat16s;'; + +if Openpic.Execute then + begin + gpath := ExtractFilePath(OpenPic.filename); + AssignFile(Txt, OpenPic.filename); + Reset(Txt); + + while not Eof(Txt) do + begin + Readln(Txt, s); + + end; + + CloseFile(Txt); + end; + +end; + +end. diff --git a/EditMat.dfm b/EditMat.dfm index c6ff9bb..07299c9 100644 --- a/EditMat.dfm +++ b/EditMat.dfm @@ -120,11 +120,14 @@ object EditMatForm: TEditMatForm TabOrder = 0 end object AddCellButton: TButton - Left = 396 - Top = 28 - Width = 75 + Left = 398 + Top = 17 + Width = 91 Height = 25 + Hint = 'bmp must match internal format' Caption = 'Add Cell' + ParentShowHint = False + ShowHint = True TabOrder = 1 OnClick = AddCellButtonClick end @@ -141,8 +144,21 @@ object EditMatForm: TEditMatForm '8-bit Transparent' '16-bit 565' '16-bit 1555 Transparent' - '16-bit 4444' - '32-bit') + '16-bit 4444 (custom engine)' + '24-bit 888 (custom engine)' + '32-bit 8888 (custom engine)') + end + object RemoveCellButton: TButton + Left = 397 + Top = 47 + Width = 92 + Height = 25 + Hint = 'Removes selected cell' + Caption = 'Remove Cell' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + OnClick = RemoveCellButtonClick end end object OpenPic: TOpenPictureDialog diff --git a/EditMat.pas b/EditMat.pas index a5f0787..4e68761 100644 --- a/EditMat.pas +++ b/EditMat.pas @@ -23,6 +23,7 @@ TEditMatForm = class(TForm) AddCellButton: TButton; FormatComboBox: TComboBox; Label4: TLabel; + RemoveCellButton: TButton; procedure FormShow(Sender: TObject); procedure CellsListBoxClick(Sender: TObject); procedure MipsListBoxClick(Sender: TObject); @@ -31,6 +32,8 @@ TEditMatForm = class(TForm) procedure Update; procedure FormatComboBoxClick(Sender: TObject); procedure OKButtonClick(Sender: TObject); + procedure RemoveCellButtonClick(Sender: TObject); + procedure CreateMipMapsFromCell(BMPArray:Tbmparray;CellBMP:Tbitmap); private { Private declarations } public @@ -65,7 +68,7 @@ procedure TEditMatForm.AddCellButtonClick(Sender: TObject); if UpperCase(ExtractFileExt(Openpic.FileName)) = '.BMP' then begin - loadbmp.HandleType := bmDIB; + //loadbmp.HandleType := bmDIB; @@ -76,11 +79,11 @@ procedure TEditMatForm.AddCellButtonClick(Sender: TObject); // 8 bit non transparent - if (FormatComboBox.ItemIndex = 0) then + if (FormatComboBox.ItemIndex < 2) then begin if fmt <> pf8bit then begin - showmessage('bitmap is not 8-bit'); + showmessage('bitmap is '+BMPFMTtoStr(inputBMPFormat)+' not 8-bit'); exit; end @@ -88,7 +91,14 @@ procedure TEditMatForm.AddCellButtonClick(Sender: TObject); begin editA.AddCellFromBMP(loadbmp); editA.ConvertBMPPal; - editA.fmt:= '8-bit INDEXED'; + if (FormatComboBox.ItemIndex = 0) then + editA.fmt:= '8-bit INDEXED' + else + begin + editA.fmt:= '8-bit trans INDEXED'; + MipRadioGroup.Enabled:=false; + MipRadioGroup.ItemIndex :=0; + end; end; end; @@ -96,7 +106,7 @@ procedure TEditMatForm.AddCellButtonClick(Sender: TObject); begin if inputBMPFormat <> bf16bit565 then begin - showmessage('bitmap is not 16-bit RGB565'); + showmessage('bitmap is '+BMPFMTtoStr(inputBMPFormat)+' not 16-bit RGB565'); exit; end @@ -111,7 +121,7 @@ procedure TEditMatForm.AddCellButtonClick(Sender: TObject); begin if inputBMPFormat <> bf16bitA1555 then begin - showmessage('bitmap is not 16-bit ARGB1555'); + showmessage('bitmap is '+BMPFMTtoStr(inputBMPFormat)+' not 16-bit ARGB1555'); exit; end @@ -119,14 +129,17 @@ procedure TEditMatForm.AddCellButtonClick(Sender: TObject); begin editA.AddCellFromBMP(loadbmp); editA.fmt:= '16-bit ARGB1555'; + MipRadioGroup.Enabled:=false; + MipRadioGroup.ItemIndex :=0; end; end; + {internal format is actually 32-bit here} if (FormatComboBox.ItemIndex = 4) then begin - if (inputBMPFormat <> bf16bitA444) then + if (inputBMPFormat <> bf16bitA444) and (inputBMPFormat <> bf32bit) then begin - showmessage('bitmap is not 16-bit ARGB4444'); + showmessage('bitmap is '+BMPFMTtoStr(inputBMPFormat)+' not 32-bit or 16-bit RGBA4444'); exit; end @@ -134,14 +147,68 @@ procedure TEditMatForm.AddCellButtonClick(Sender: TObject); begin editA.AddCellFromBMP(loadbmp); editA.fmt:= '16-bit RGBA4444'; + MipRadioGroup.Enabled:=false; + MipRadioGroup.ItemIndex :=0; end; end; + if (FormatComboBox.ItemIndex = 5) then + begin + if (inputBMPFormat <> bf24bit) then + begin + showmessage('bitmap is '+BMPFMTtoStr(inputBMPFormat)+' not 24-bit'); + exit; + end + + else + begin + editA.AddCellFromBMP(loadbmp); + editA.fmt:= '24-bit RGB'; + end; + end; + + if (FormatComboBox.ItemIndex = 6) then + begin + if (inputBMPFormat <> bf32bit) then + begin + showmessage('bitmap is '+BMPFMTtoStr(inputBMPFormat)+' not 32-bit'); + exit; + end + + else + begin + editA.AddCellFromBMP(loadbmp); + editA.fmt:= '32-bit RGBA'; + MipRadioGroup.Enabled:=false; + MipRadioGroup.ItemIndex :=0; + end; + end; + + resize.HandleType := bmDIB; size:=1; if IsBMPmipsOK(loadbmp) then begin + + if (loadbmp.Height > 256) or (loadbmp.Width > 256) then + begin + with TTaskDialog.Create(self) do + try + Caption := 'Mat16'; + Title := 'Create Mip-Maps'; + Text := 'Do you want to continue even though JK doesnt support Mip-Maps for images >256?'; + CommonButtons := [tcbYes, tcbNo]; + DefaultButton := tcbNo; + MainIcon := tdiNone; + if Execute then + if ModalResult = mrNo then + MipRadioGroup.ItemIndex:=0;; + finally + Free; + end; + end; + for i := 0 to (MipRadioGroup.ItemIndex - 1) do begin size:=size / 2; @@ -160,12 +227,12 @@ procedure TEditMatForm.AddCellButtonClick(Sender: TObject); begin // resample:= Conv24bitTo16(resize,3,2,3); resample:= DitherTo16(resize); - editA.AddSubMipMapFromBMP( resample); + editA.AddSubMipMapFromBMP(resample); resample.free; end; - - + if fmt = pf24bit then + editA.AddSubMipMapFromBMP(resize); end; end; @@ -217,7 +284,8 @@ procedure TEditMatForm.FormClose(Sender: TObject; var Action: TCloseAction); MipsListBox.Clear; // if assigned(image1.Picture.Bitmap) then image1.Picture.Bitmap.Free; -//image1.Picture.Bitmap:=nil; +image1.Picture:=nil; + end; @@ -235,10 +303,19 @@ procedure TEditMatForm.Update; if editA.GetCellCount = 0 then begin OKButton.ModalResult:=mrCancel; + RemoveCellButton.Enabled:=false; + FormatComboBox.Enabled:=true; + MipRadioGroup.Enabled:=true; if FormatComboBox.ItemIndex = -1 then - AddCellButton.Enabled:=false + begin + AddCellButton.Enabled:=false; + //RemoveCellButton.Enabled:=false; + end else + begin AddCellButton.Enabled:=true; + //RemoveCellButton.Enabled:=true; + end; end else begin @@ -250,6 +327,7 @@ procedure TEditMatForm.Update; MipRadioGroup.ItemIndex := editA.GetMipCount; MipRadioGroup.Enabled:=false; AddCellButton.Enabled:=true; + RemoveCellButton.Enabled:=true; end; if editA.GetCellCount >= 16 then @@ -261,16 +339,38 @@ procedure TEditMatForm.Update; FormatComboBox.ItemIndex:=0; if ContainsText(editA.fmt, '8-bit trans INDEXED') then + begin FormatComboBox.ItemIndex:=1; + MipRadioGroup.Enabled:=false; + MipRadioGroup.ItemIndex :=0; + end; if ContainsText(editA.fmt, '16-bit RGB565') then FormatComboBox.ItemIndex:=2; if ContainsText(editA.fmt, '16-bit ARGB1555') then + begin FormatComboBox.ItemIndex:=3; + MipRadioGroup.Enabled:=false; + MipRadioGroup.ItemIndex :=0; + end; - if ContainsText(editA.fmt, 'RGBA') then + if ContainsText(editA.fmt, 'RGBA4444') then + begin FormatComboBox.ItemIndex:=4; + MipRadioGroup.Enabled:=false; + MipRadioGroup.ItemIndex :=0; + end; + + if ContainsText(editA.fmt, '24-bit RGB') then + FormatComboBox.ItemIndex:=5; + + if ContainsText(editA.fmt, '32-bit RGBA') then + begin + FormatComboBox.ItemIndex:=6; + MipRadioGroup.Enabled:=false; + MipRadioGroup.ItemIndex :=0; + end; FormatComboBox.Enabled:=false; end; @@ -325,4 +425,76 @@ procedure TEditMatForm.OKButtonClick(Sender: TObject); end; +procedure TEditMatForm.RemoveCellButtonClick(Sender: TObject); +var +CellIndexToRemove,i:Integer; +NewBMPArray:Tbmparray; +tempBMP:tbitmap; +begin +NewBMPArray:=Tbmparray.Create; +NewBMPArray.fmt:=editA.fmt; + +for i := 0 to (CellsListBox.Items.Count - 1) do + if CellsListBox.Selected[i] then CellIndexToRemove:=i; + +for i := 0 to (editA.GetCellCount - 1) do + begin + if i<>CellIndexToRemove then + begin + tempBMP:=edita.GetCell(i); {function creates bmp} + NewBMPArray.AddCellFromBMP( tempBMP ); + + if ContainsText(NewBMPArray.fmt,'INDEXED') then + NewBMPArray.ConvertBMPPal; + CreateMipMapsFromCell( NewBMPArray,tempBMP ); + tempBMP.Free; + tempBMP:=nil; + end; + end; + +edita.Assign(NewBMPArray); +NewBMPArray.Free; +update; +end; + +procedure TEditMatForm.CreateMipMapsFromCell(BMPArray:Tbmparray;CellBMP:Tbitmap); +var +resize,resample:tbitmap; +size:double; +i:Integer; +fmt:TPixelFormat; +begin + resize := Tbitmap.Create; + resize.HandleType := bmDIB; + size:=1; + fmt:= CellBMP.PixelFormat; + if IsBMPmipsOK(CellBMP) then + begin + for i := 0 to (MipRadioGroup.ItemIndex - 1) do + begin + size:=size / 2; + scaleimage(CellBMP,resize,size); //converts bmps to 24bit + + //reduce colors back to 8-bit using original pallette + //https://docwiki.embarcadero.com/Libraries/Sydney/en/Vcl.Imaging.GIFImg.TDitherMode + if fmt = pf8bit then + begin + resample:=ReduceColors(resize,rmPalette,dmNearest,8,CellBMP.Palette); //palette must still exist after conversion + BMPArray.AddSubMipMapFromBMP(resample); + resample.free; + end; + + if fmt = pf16bit then + begin + // resample:= Conv24bitTo16(resize,3,2,3); + resample:= DitherTo16(resize); + BMPArray.AddSubMipMapFromBMP( resample); + resample.free; + end; + + end; + end; +resize.Free; +end; + end. diff --git a/GloabalVars.pas b/GloabalVars.pas new file mode 100644 index 0000000..0f903d5 --- /dev/null +++ b/GloabalVars.pas @@ -0,0 +1,9 @@ +unit GloabalVars; + +interface + +var +jkpath: string; +implementation + +end. diff --git a/MAIN.PAS b/MAIN.PAS index e1c8a9d..337ebdc 100644 --- a/MAIN.PAS +++ b/MAIN.PAS @@ -4,7 +4,7 @@ interface uses SysUtils, Windows, Messages, Classes, Graphics, Controls, - Forms, Dialogs, StdCtrls, ImgList, Menus, Grids, ComCtrls, ExtCtrls, + Forms, vcl.Dialogs, StdCtrls, ImgList, Menus, Grids, ComCtrls, ExtCtrls, Buttons, ToolWin, ExtDlgs, Util, clipbrd, ShellAPI, gobgoo, Registry, SaveDLGUnit, adpMRU, System.ImageList,MATImage,BMParrays,ColorMap,MATHeaders,CMPHeaders, System.IOUtils,StrUtils,Set8bitFormatOnOpen,BMP_IO; @@ -62,8 +62,6 @@ type GroupBox1: TGroupBox; ViewasTransparent1: TMenuItem; ViewTiled2: TMenuItem; - CloseImage1: TMenuItem; - N3: TMenuItem; Panel2: TPanel; Zoom1: TMenuItem; In1: TMenuItem; @@ -141,6 +139,7 @@ type procedure updateCMPcomboBox(container:string); procedure TrackBarChange; procedure Createnewmatfrombmps1Click(Sender: TObject); + procedure EditMTS1Click(Sender: TObject); end; var @@ -150,7 +149,6 @@ var numframes: integer; savefname: string; addcell: boolean; - jkpath: string; motspath: string; isbatch: boolean; adpMRU: TadpMRU; @@ -160,7 +158,7 @@ var implementation uses about_unit, Batch, - gobform, ViewtileUnit, mess_frm,options, EditMat; + gobform, ViewtileUnit, mess_frm,options, EditMat,EditMTS,GloabalVars; {$R *.DFM} @@ -208,12 +206,21 @@ begin BMPArray.Assign(BMPA); tempBMP:=(BMPArray.GetCell(0)); - if (Mat.GetMatFormat=(TFormat.RGBA4444)) or (Mat.GetMatFormat=(TFormat.RGBA5551)) then + if (Mat.GetMatFormat=(TFormat.RGBA4444)) or (Mat.GetMatFormat=(TFormat.RGBA5551)) or (Mat.GetMatFormat=(TFormat.RGBA8888)) then begin - tempBMP:=(BMPArray.GetAlphaCellForDisplay(0)); + PremultiplyAlpha(tempBMP); Draw32bitImageOnGrid(tempBMP); end; + if Mat.GetMatFormat=(TFormat.RGB888) then + begin + Image1.Picture.Bitmap.Assign(tempBMP); + if tempBMP.PixelFormat =pf8bit then + begin + Image1.Picture:=nil; + end; + end; + if Mat.GetMatFormat=(TFormat.ARGB1555) then begin Draw16bitImageOnGrid(tempBMP); @@ -310,11 +317,17 @@ begin tmpBMP:=(BMPArray.GetBMP(Cell_TrackBar.Position,Mip_TrackBar.Position)); if (tmpBMP.PixelFormat = pf32bit) then - Draw32bitImageOnGrid(tmpBMP); + begin + PremultiplyAlpha(tmpBMP); + Draw32bitImageOnGrid(tmpBMP); + end; if (tmpBMP.PixelFormat = pf16bit) then image1.picture.Bitmap.Assign(tmpBMP); + if (tmpBMP.PixelFormat = pf24bit) then + image1.picture.Bitmap.Assign(tmpBMP); + if (bitmap.PixelFormat = pfCustom) then //ARGB1555 Draw16bitImageOnGrid(tmpBMP); @@ -350,6 +363,7 @@ end; procedure TMainForm.FileSaveAs(Sender: TObject); var Mat: TMAT; +MatName:string; begin Screen.Cursor := crHourGlass; SaveDialog.FileName := ChangeExt(OpenDialog.FileName, ''); @@ -370,7 +384,8 @@ begin if UpperCase(ExtractFileExt(SaveDialog.FileName)) = '.MAT16S' then begin - BMPArray.SaveMTS(SaveDialog.FileName); + MatName:=ChangeFileExt(SaveDialog.FileName, '.mat'); + BMPArray.SaveMTS(MatName); end; end; @@ -608,49 +623,80 @@ begin end; procedure TMainForm.BatchConvertBMPs1Click(Sender: TObject); -//var -// I, Count: integer; -// BatchBitmap: TBitmap; -// savename, mcfname: string; -// StartTime, EndTime: DWORD; +var + I: integer; + LoadBMParray:TBMParray; + LoadMat: TMAT; + gpath, mpath: string; + begin - // isbatch:=TRUE; + OpenDialogBatch.Filter := + 'mat16 script with bitmaps|*mat16s'; +Screen.Cursor := crHourGlass; - MATSaveDlg.Show; - isbatch := True; + if OpenDialogBatch.Execute then + begin + Screen.Cursor := crHourGlass; -end; + BatchForm.ProgressBar1.Position := 0; + BatchForm.Show; + BatchForm.Memo1.Lines.Clear; + BatchForm.Memo1.Lines.Add(IntToStr(OpenDialogBatch.Files.Count) + + ' File(s) selected to convert'); -procedure TMainForm.BatchConvertMATBMP1Click(Sender: TObject); + BatchForm.ProgressBar1.Max := OpenDialogBatch.Files.Count-1; - var + for I := 0 to OpenDialogBatch.Files.Count - 1 do + begin + BatchForm.ProgressBar1.Position := i; + + if UpperCase(ExtractFileExt(OpenDialogBatch.Files[I])) = '.MAT16S' then + begin + LoadBMParray:=TBMPARRAY.Create; + try + LoadBMParray.OpenMTS(OpenDialogBatch.Files[I]); + LoadMat:=TMAT.CreateFromBMPArray(LoadBMParray); + mpath:=ExtractFilePath(OpenDialogBatch.Files[I])+LoadBMParray.name; + if (UpperCase(ExtractFileExt(mpath)) <> '.MAT') then + begin + raise Exception.Create('Save MAT wrong file type '+mpath); + end; + LoadMat.SaveMat(ExtractFilePath(OpenDialogBatch.Files[I])+LoadBMParray.name); + except + On e:exception do + begin + ShowMessage(E.ClassName+' error raised, with message : '+E.Message); + LoadBMParray.Free; + LoadMat.Free; + Screen.Cursor := crDefault; + exit; + end; + end; + BatchForm.Memo1.Lines.Add('Saved MAT: '+ExtractFilePath(OpenDialogBatch.Files[I])+LoadBMParray.name ); + LoadBMParray.Free; + LoadMat.Free; + end; + end; + end; + BatchForm.Memo1.Lines.Add('-Done-'); + Screen.Cursor := crDefault; +end; + +procedure TMainForm.BatchConvertMATBMP1Click(Sender: TObject); +var i,j,k: integer; - savebitmap: Tbitmap; - bestcmp, gpath, mpath, fext, mname: string; -// f: file; Mat: TMAT; - // matFormatHeader:TMatHeader; - pos:longint; - tempA:TBMPArray; - MatInfoList:Tstringlist; + pos:longint; + tempA:TBMPArray; begin OpenDialogBatch.Filter := 'mat texture (*.mat)|*.MAT'; - // savebitmap := Tbitmap.Create; - gpath := ExtractFilePath(label1.Caption); - fext := ExtractName(label1.Caption); - fext := ChangeFileExt(fext, ''); - gpath := gpath + fext; - Screen.Cursor := crHourGlass; - CreateDir(gpath); - //BatchForm.Show; +Screen.Cursor := crHourGlass; - i:=0; if OpenDialogBatch.Execute then begin - gpath := ExtractFilePath(OpenDialogBatch.Files[I]); Screen.Cursor := crHourGlass; BatchForm.ProgressBar1.Position := 0; @@ -660,42 +706,16 @@ OpenDialogBatch.Filter := BatchForm.Memo1.Lines.Add(IntToStr(OpenDialogBatch.Files.Count) + ' File(s) selected to convert'); - BatchForm.ProgressBar1.Max := OpenDialogBatch.Files.Count-1; - // starttime := GetTickCount; - for I := 0 to OpenDialogBatch.Files.Count - 1 do - begin - BatchForm.ProgressBar1.Position := i; - - bestcmp := GetbestCMP(OpenDialogBatch.Files[I], jkpath); - - pos:=GetGOBFileOffset(jkpath,bestcmp); - MainCMP.LoadCMPFromFile(jkpath, pos); - - // mainform.gridPalette.Repaint; - - Mat:=TMAT.Create(TFormat.BMP); - Mat.SetCMP(defCmppal); - tempA:= Mat.LoadFromFile(OpenDialogBatch.Files[I]); - - mess.Memo1.lines.Add(OpenDialogBatch.Files[I]); - MatInfoList:=Mat.HeadersToJSON; - mess.Memo1.lines.AddStrings(MatInfoList); - - tempA.SaveMTS(OpenDialogBatch.Files[I]); - BatchForm.Memo1.Lines.Add('Saved: ' - + TPath.GetFileNameWithoutExtension(OpenDialogBatch.Files[I]) - + ' cmp: ' + bestcmp); - - Mat.Free; - tempA.Free; - MatInfoList.Free; - end; + for I := 0 to OpenDialogBatch.Files.Count - 1 do + begin + BatchForm.ProgressBar1.Position := i; + BatchForm.Memo1.Lines.Add(GobMatSavetoBMP('', OpenDialogBatch.Files[I],FileOffsets,CMPOffsets,false)); + end; end; BatchForm.Memo1.Lines.Add('-Done-'); Screen.Cursor := crDefault; - end; procedure TMainForm.Button1Click(Sender: TObject); @@ -814,6 +834,12 @@ begin end; +procedure TMainForm.EditMTS1Click(Sender: TObject); +begin + EditMTSForm.Show; + +end; + procedure TMainForm.Draw16bitImageOnGrid(bmp:Tbitmap); var gridBMP,remap:tbitmap; @@ -839,6 +865,7 @@ procedure TMainForm.Draw32bitImageOnGrid(bmp:Tbitmap); gridBMP,remap:tbitmap; begin gridBMP:=Tbitmap.create; + gridBMP.PixelFormat:=pf32bit; try RenderGrid(gridBMP,bmp.Height,bmp.Width,1,clGray,clLtGray); Blend(gridBMP,bmp); @@ -1353,8 +1380,20 @@ begin begin LoadBMParray:=TBMPARRAY.Create; + try LoadBMParray.OpenMTS(FileName); + except + On e:exception do + begin + ShowMessage(E.ClassName+' error raised, with message : '+E.Message); + LoadBMParray.Free; + Screen.Cursor := crDefault; + exit; + end; + + end; + Cell_TrackBar.Position := 0; image1.Repaint; @@ -1362,9 +1401,7 @@ begin LoadMat.matFormat:=LoadMat.StrToFormat(LoadBMParray.fmt); BMPArrayDisplay(LoadBMParray,LoadMat); //frees bmpA and Tmat - - - end; + end; MainForm.Caption := 'Mat16 - ' + extractfilename(FileName); adpMRU.AddItem(OpenPic.FileName); diff --git a/MAIN.dfm b/MAIN.dfm index 69576ea071baecfa99643aec49035e1e89fd99fc..22ff957aafb6b061fc6edbe9fe8beb3321924556 100644 GIT binary patch delta 235 zcmeAVz8fU)pNk>H*U{6@%|FPO!9c)kqkt2OtgL@QYMw%(LT+M-LVgj5GBhhz&@Wd= z$}Lcztjjrb@&y))$rbE8n;lr!a40J|C6**-C^+Zmm8BMyz?Fj(7b}$Hg9JA5)$(zK zWfo^9<)m_Ku94Zrtg4EtO9NyXL@~&+a(%G&$pH#pva*;eK}sNsC+|{l-<+g)lv&I< eII|=}!8I>EGcQ#kB(<WXv?x_Uce9mhC<_4Q!A&>- delta 247 zcmcZ`)E_MHpNk>H*U{6@%|FPO!9bv9qkt2Okf47-YMw%(g0EwULVl5glW)N00+tR= z5n-pqlH?2p=lr~~)S?oQxO(wsX}(&%%?o9AGD}IJN^5|$m*j(#O|Dn)QdB^b28x5E z4b74=OF&j>PQJ*mG?`OT#gyAQC%-t=GdD3k)sWpev7jU~KaUL}r~npa_s?_A$xO~> v7eJ_-ET|yDXgqnMoXln;#RJU34qmA#nF`){nduoNKudIiwru854P^lU8E8za diff --git a/MATImage.pas b/MATImage.pas index b7acba7..7a3db2f 100644 --- a/MATImage.pas +++ b/MATImage.pas @@ -1,10 +1,10 @@ unit MATImage; interface -uses Windows,Graphics, SysUtils, Classes, MATHeaders, Color16,ColorMap,BMParrays,CMPHeaders,BMP_IO; +uses Windows,Graphics, SysUtils, Classes, MATHeaders, Color16,ColorMap,BMParrays,CMPHeaders,BMP_IO,System.StrUtils; Type - TFormat = (INDEX,INDEXT,INDEXCMP,INDEXTCMP,COLOR8,RGB565,ARGB1555, RGBA5551, RGBA4444,BMP); + TFormat = (INDEX,INDEXT,INDEXCMP,INDEXTCMP,COLOR8,RGB565,ARGB1555, RGBA5551, RGBA4444,RGB888,RGBA8888,BMP); TMAT = class private @@ -184,6 +184,44 @@ constructor TMAT.Create(format:TFormat); alpha_BitDif:=4; end; + if (matFormat = RGB888) then + begin + ColorMode:=1; + + bits:=24; + redbits:=8; + greenbits:=8; + bluebits:=8; + shiftR:=16; + shiftG:=8; + shiftB:=0; + RedBitDif:=0; + GreenBitDif:=0; + BlueBitDif:=0; + alpha_bpp:=8; + alpha_sh:=0; + alpha_BitDif:=0; + end; + + if (matFormat = RGBA8888) then + begin + ColorMode:=2; + + bits:=32; + redbits:=8; + greenbits:=8; + bluebits:=8; + shiftR:=24; + shiftG:=16; + shiftB:=8; + RedBitDif:=0; + GreenBitDif:=0; + BlueBitDif:=0; + alpha_bpp:=8; + alpha_sh:=0; + alpha_BitDif:=0; + end; + end; end; constructor TMAT.CreateFromBMPArray(ABMPARRAY:TBMPARRAY); @@ -233,7 +271,15 @@ destructor TMAT.Destroy; // self.bmap.Free; freeandnil(bmap); CMPData:=default(TCMPPal); - +// if Bitstream<>nil then +// Bitstream.Clear; + SetLength(Imagedata16,0, 0); + SetLength(Imagedata8, 0, 0); + + SetLength(matTextureHeaderA,0); + SetLength(matColorHeaderA,0); + SetLength(matMipmapHeaderA,0); + SetLength(ImageDataIndex,0); inherited; end; @@ -324,6 +370,7 @@ procedure TMAT.AddCellFromBMP(bmap: TBitmap); bmap.free; end; + function TMAT.SetSamplePerChannel(SourceRGBA:tagRGBQuad):tagRGBQuad; begin result.rgbRed:=SourceRGBA.rgbRed shr matFormatHeader.RedBitDif; @@ -335,8 +382,6 @@ function TMAT.SetSamplePerChannel(SourceRGBA:tagRGBQuad):tagRGBQuad; result.rgbReserved:=SourceRGBA.rgbReserved and 1; end; - - //Adds pixel data to a Tcolor array //each row is a cell that contains main image and any mips for that cell procedure TMAT.Convert(IsSubMipMap: Boolean); @@ -346,6 +391,9 @@ procedure TMAT.Convert(IsSubMipMap: Boolean); TRGBQuadArray = array[0..PixelCountMax - 1] of TRGBQuad; pRGBQuadArray = ^TRGBQuadArray; + TRGBTripleArray = ARRAY[Word] of TRGBTriple; + pRGBTripleArray = ^TRGBTripleArray; + TByteArray = array[0..32767] of Byte; PByteArray = ^TByteArray; @@ -353,9 +401,11 @@ procedure TMAT.Convert(IsSubMipMap: Boolean); i,h,w,cellInedx:integer; DestRGBA:tagRGBQuad; RGBQuadLineArray: pRGBQuadArray; + RGBTrippleLineArray:pRGBTripleArray; IndexArray: PByteArray; row16:PWordArray; BMPFormat:TBMPFormat; + Dest16bitPixel:word; begin //if IsSubMipMap then @@ -389,6 +439,7 @@ procedure TMAT.Convert(IsSubMipMap: Boolean); end; + {internal 32-bit bmp to 16-bit RGBA 4444} if ( (bits = 16) and (bmap.PixelFormat = pf32bit) )then begin for h := 0 to bmap.Height - 1 do @@ -396,14 +447,46 @@ procedure TMAT.Convert(IsSubMipMap: Boolean); RGBQuadLineArray := bmap.ScanLine[h]; for w := 0 to bmap.Width - 1 do begin - DestRGBA:=SetSamplePerChannel(RGBQuadLineArray[w]); - self.ImageData16[cellInedx][Self.ImageDataIndex[cellInedx]].Create(DestRGBA.rgbRed,DestRGBA.rgbGreen,DestRGBA.rgbBlue,DestRGBA.rgbReserved,matFormatHeader); + DestRGBA:=SetSamplePerChannel(RGBQuadLineArray^[w]); + Dest16bitPixel:=DestRGBA.rgbRed shl 12 or DestRGBA.rgbGreen shl 8 or DestRGBA.rgbBlue shl 4 or DestRGBA.rgbReserved shl 0; + //Dest16bitPixel:=65535; {all white test} + //Dest16bitPixel:=65520; {all white test 0 alpha} + bitstream.Write(Dest16bitPixel, sizeof(word)); + // self.ImageData16[cellInedx][Self.ImageDataIndex[cellInedx]].Create(DestRGBA.rgbRed,DestRGBA.rgbGreen,DestRGBA.rgbBlue,DestRGBA.rgbReserved,matFormatHeader); inc(Self.ImageDataIndex[cellInedx]); end; //w end; //h end; + if ( (bits = 24) and (bmap.PixelFormat = pf24bit) )then + begin + for h := 0 to bmap.Height - 1 do + begin + RGBTrippleLineArray := bmap.ScanLine[h]; + for w := 0 to bmap.Width - 1 do + begin + bitstream.Write(RGBTrippleLineArray^[w],sizeof(TRGBTriple)); + inc(Self.ImageDataIndex[cellInedx]); + end; + end; + end; + + if ( (bits = 32) and (bmap.PixelFormat = pf32bit) )then + begin + for h := 0 to bmap.Height - 1 do + begin + RGBQuadLineArray := bmap.ScanLine[h]; + for w := 0 to bmap.Width - 1 do + begin + bitstream.Write(RGBQuadLineArray^[w],sizeof(TRGBQuad)); + inc(Self.ImageDataIndex[cellInedx]); + end; + end; + + end; + + if ( (bits = 16) and ( (BMPFormat = bf16bitA1555) or (BMPFormat = bf16bit565) ) )then begin for h := 0 to bmap.Height - 1 do @@ -438,6 +521,7 @@ procedure TMAT.SaveMat(fname: string); I,N: Integer; Abytes: array of byte; begin + ms := TMemoryStream.Create; ms.Write(matFormatHeader, sizeof(matFormatHeader)); @@ -472,6 +556,20 @@ procedure TMAT.SaveMat(fname: string); end; + if matFormatHeader.bits = 24 then + begin + SetLength(Abytes, ImageDataIndex[N]*3); + bitstream.ReadBuffer(Abytes[0],ImageDataIndex[N]*3); + ms.Write(Abytes[0], ImageDataIndex[N]*3); + end; + + if matFormatHeader.bits = 32 then + begin + SetLength(Abytes, ImageDataIndex[N]*4); + bitstream.ReadBuffer(Abytes[0],ImageDataIndex[N]*4); + ms.Write(Abytes[0], ImageDataIndex[N]*4); + end; + if matFormatHeader.bits = 8 then begin //for I:= 0 to Length(ImageData8[N]) - 1 do @@ -493,6 +591,10 @@ procedure TMAT.SaveMat(fname: string); end; + {8.3 filename bug workaround} + if ContainsText(fname,'~1') then + fname:= StringReplace(fname, '~1', '_1', [rfReplaceAll, rfIgnoreCase]); + Bitstream.Free; ms.SaveToFile(fname); Ms.Free; @@ -651,6 +753,7 @@ function TMAT.LoadFromFile(filename: string;pos: longint=0): TBMPARRAY; //add cells for i := 0 to matFormatHeader.cel_count - 1 do begin + if Assigned(self.bmap) then self.bmap.Assign(nil); BlockRead(f, matMipmapHeaderA[i], SizeOf(matMipmapHeaderA[i])); if (matMipmapHeaderA[i].SizeX >8000) or (matMipmapHeaderA[i].SizeX <=0) then @@ -690,6 +793,8 @@ function TMAT.LoadFromFile(filename: string;pos: longint=0): TBMPARRAY; ARGB1555:result.fmt:='16-bit ARGB1555'; RGBA4444:result.fmt:='16-bit RGBA4444'; RGBA5551:result.fmt:='16-bit RGBA5551'; + RGB888:result.fmt:='24-bit RGB'; + RGBA8888:result.fmt:='32-bit RGBA'; INDEX:result.fmt:='8-bit INDEXED'; INDEXT:result.fmt:='8-bit trans INDEXED'; COLOR8:result.fmt:='8-bit COLOR'; @@ -697,8 +802,9 @@ function TMAT.LoadFromFile(filename: string;pos: longint=0): TBMPARRAY; INDEXTCMP:result.fmt:='8-bit INDEXED trans int CMP'; end; - - // bmap.SaveToFile('D:\TestBMP\lastcell.bmp'); + {$IFDEF DEBUG} + bmap.SaveToFile('D:\TestBMP\lastcell.bmp'); + {$ENDIF} imageformat:=matformat; tempBMP.Free; CloseFile(f); @@ -716,6 +822,10 @@ function TMAT.StrToFormat(str:string):TFORMAT; result:= TFORMAT.ARGB1555; if str.Equals('16-bit RGBA4444') then result:= TFORMAT.RGBA4444; + if str.Equals('24-bit RGB') then + result:= TFORMAT.RGB888; + if str.Equals('32-bit RGBA') then + result:= TFORMAT.RGBA8888; if str.Equals('16-bit RGBA5551') then result:= TFORMAT.RGBA5551; if str.Equals('8-bit INDEXED') then @@ -744,6 +854,7 @@ procedure TMAT.toBMP(w, h: integer); inrow: pRGBQuadArray; src: word; cmp:TCMPPal; + sl: PUInt64; // Bsrc:byte; // IndexArray: PByteArray; begin @@ -807,17 +918,17 @@ procedure TMAT.toBMP(w, h: integer); matformat:=TFormat.RGBA4444; bmap.PixelFormat := pf32bit; bmap.HandleType := bmDIB; - bmap.Alphaformat := afDefined; + bmap.Alphaformat := afIgnored; {setting as defined seems to cause pre multiplication after conversion} for j := 0 to bmap.Height - 1 do begin inrow := bmap.ScanLine[j]; for i := 0 to bmap.Width - 1 do begin BlockRead(f, src, sizeof(src)); - inrow[i].rgbRed := ((src and 61440) shr 12) * 17; - inrow[i].rgbGreen := ((src and 3840) shr 8) * 17; - inrow[i].rgbBlue := ((src and 240) shr 4) * 17; - inrow[i].rgbReserved := ((src and 15) shr 0) * 17; + inrow^[i].rgbRed := ((src and 61440) shr 12) * 17; + inrow^[i].rgbGreen := ((src and 3840) shr 8) * 17; + inrow^[i].rgbBlue := ((src and 240) shr 4) * 17; + inrow^[i].rgbReserved := ((src and 15) shr 0) * 17; // inrow[i].rgbRed := ((src and 61440) shr 12) shl 4; // inrow[i].rgbGreen := ((src and 3840) shr 8) shl 4; @@ -827,10 +938,31 @@ procedure TMAT.toBMP(w, h: integer); end; - //bmap.TransparentColor:= bmap.canvas.pixels[0,0]; - bmap.TransparentMode:= tmAuto; end; + if (matFormatHeader.bits = 24) then + begin + matformat:=TFormat.RGB888; + bmap.PixelFormat := pf24bit; + bmap.HandleType := bmDIB; + + for h := 0 to bmap.Height - 1 do + BlockRead(f, bmap.ScanLine[h]^, 3 * bmap.Width); + end; + + + if (matFormatHeader.bits = 32) and (matFormatHeader.ColorMode = 2) and (matFormatHeader.alpha_bpp = 8) then + begin + matformat:=TFormat.RGBA8888; + bmap.PixelFormat := pf32bit; + bmap.HandleType := bmDIB; + bmap.Alphaformat := afIgnored ; {setting as defined seems to cause pre multiplication after conversion} + + for h := 0 to bmap.Height - 1 do + BlockRead(f, bmap.ScanLine[h]^, 4 * bmap.Width); + + end; + //indexed if (matFormatHeader.bits = 8) and (matFormatHeader.ColorMode = 0) and (matFormatHeader.mat_Type = 2) then begin diff --git a/Mat16.DPR b/Mat16.DPR index b53bbaa..9234ea0 100644 --- a/Mat16.DPR +++ b/Mat16.DPR @@ -1,9 +1,15 @@ program Mat16; -{$R *.dres} + uses + {$IFDEF DEBUG} FastMM4 in 'FastMM4\FastMM4.pas', + FastMM4DataCollector in 'FastMM4\FastMM4DataCollector.pas', + FastMM4LockFreeStack in 'FastMM4\FastMM4LockFreeStack.pas', + FastMM4Messages in 'FastMM4\FastMM4Messages.pas', + {$ENDIF} + //FastMM4 in 'FastMM4\FastMM4.pas', Forms, MAIN in 'MAIN.PAS' {MainForm}, Batch in 'Batch.pas' {BatchForm}, @@ -23,13 +29,12 @@ uses ColorMap in 'ColorMap.pas', options in 'options.pas' {OptionsForm}, CMPHeaders in 'CMPHeaders.pas', - FastMM4DataCollector in 'FastMM4\FastMM4DataCollector.pas', - FastMM4LockFreeStack in 'FastMM4\FastMM4LockFreeStack.pas', - FastMM4Messages in 'FastMM4\FastMM4Messages.pas', + CNDHeaders in 'CNDHeaders.pas', Set8bitFormatOnOpen in 'Set8bitFormatOnOpen.pas' {Set8bitFormatForm}, EditMat in 'EditMat.pas' {EditMatForm}, - BMP_IO in 'BMP_IO.pas'; + BMP_IO in 'BMP_IO.pas', + GloabalVars in 'GloabalVars.pas'; // MemCheck; {$R *.RES} @@ -47,7 +52,10 @@ MemChk; } // ReportMemoryLeaksOnShutdown := DebugHook <> 0; // Application.CreateForm(TOptionsForm, OptionsForm); - {$INCLUDE FastMM4\FastMM4Options.inc} +// {$INCLUDE FastMM4\FastMM4Options.inc} + {$IFDEF DEBUG} + {$INCLUDE FastMM4\FastMM4Options.inc} + {$ENDIF} Application.CreateForm(TMainForm, MainForm); Application.CreateForm(Tgobview, gobview); Application.CreateForm(TViewTiled, ViewTiled); diff --git a/Mat16.dproj b/Mat16.dproj index 37963ac..0f392d4 100644 --- a/Mat16.dproj +++ b/Mat16.dproj @@ -8,7 +8,7 @@ <FrameworkType>VCL</FrameworkType> <ProjectVersion>19.2</ProjectVersion> <Base>True</Base> - <Config Condition="'$(Config)'==''">Debug</Config> + <Config Condition="'$(Config)'==''">Release</Config> <Platform Condition="'$(Platform)'==''">Win32</Platform> <TargetedPlatforms>3</TargetedPlatforms> <AppType>Application</AppType> @@ -103,6 +103,10 @@ <PropertyGroup Condition="'$(Cfg_1_Win32)'!=''"> <AppEnableRuntimeThemes>true</AppEnableRuntimeThemes> <AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode> + <VerInfo_MajorVer>1</VerInfo_MajorVer> + <VerInfo_MinorVer>0</VerInfo_MinorVer> + <VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys> + <Icon_MainIcon>Mat16_Icon.ico</Icon_MainIcon> </PropertyGroup> <PropertyGroup Condition="'$(Cfg_1_Win64)'!=''"> <AppEnableRuntimeThemes>true</AppEnableRuntimeThemes> @@ -192,30 +196,12 @@ <Overwrite>true</Overwrite> </Platform> </DeployFile> - <DeployFile LocalName="dflt_Cell0_Mip0.bmp" Configuration="Debug" Class="ProjectFile"> - <Platform Name="Win32"> - <RemoteDir>.\</RemoteDir> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> - <DeployFile LocalName="dflt_Cell0.BMP" Configuration="Debug" Class="ProjectFile"> - <Platform Name="Win32"> - <RemoteDir>.\</RemoteDir> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> <DeployFile LocalName="Mat16.exe" Configuration="Debug" Class="ProjectOutput"> <Platform Name="Win32"> <RemoteName>Mat16.exe</RemoteName> <Overwrite>true</Overwrite> </Platform> </DeployFile> - <DeployFile LocalName="dflt_Cell0_Mip1.bmp" Configuration="Debug" Class="ProjectFile"> - <Platform Name="Win32"> - <RemoteDir>.\</RemoteDir> - <Overwrite>true</Overwrite> - </Platform> - </DeployFile> <DeployClass Name="AdditionalDebugSymbols"> <Platform Name="OSX32"> <Operation>1</Operation> @@ -951,32 +937,16 @@ <Form>OptionsForm</Form> </DCCReference> <DCCReference Include="CMPHeaders.pas"/> - <DCCReference Include="FastMM4\FastMM4DataCollector.pas"/> - <DCCReference Include="FastMM4\FastMM4LockFreeStack.pas"/> - <DCCReference Include="FastMM4\FastMM4Messages.pas"/> <DCCReference Include="CNDHeaders.pas"/> <DCCReference Include="Set8bitFormatOnOpen.pas"> <Form>Set8bitFormatForm</Form> - <FormType>dfm</FormType> </DCCReference> <DCCReference Include="EditMat.pas"> <Form>EditMatForm</Form> - <FormType>dfm</FormType> </DCCReference> <DCCReference Include="BMP_IO.pas"/> + <DCCReference Include="GloabalVars.pas"/> <None Include="FastMM4\FastMM4Options.inc"/> - <RcItem Include="dflt_Cell0.BMP"> - <ResourceType>BITMAP</ResourceType> - <ResourceId>dflt_cell0</ResourceId> - </RcItem> - <RcItem Include="dflt_Cell0_Mip0.bmp"> - <ResourceType>BITMAP</ResourceType> - <ResourceId>dflt_cell0_mip0</ResourceId> - </RcItem> - <RcItem Include="dflt_Cell0_Mip1.bmp"> - <ResourceType>BITMAP</ResourceType> - <ResourceId>dflt_cell0_mip1</ResourceId> - </RcItem> <BuildConfiguration Include="Debug"> <Key>Cfg_2</Key> <CfgParent>Base</CfgParent> diff --git a/Mat16.dproj.local b/Mat16.dproj.local index e2ba080..06e6b23 100644 --- a/Mat16.dproj.local +++ b/Mat16.dproj.local @@ -19,8 +19,8 @@ <Transaction>2021/12/09 06:01:32.000.678,E:\Data\Users\8-Track\Desktop\mat16_104\dfltcmp.pas=E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.pas</Transaction> <Transaction>2021/12/09 06:05:47.000.867,E:\Data\Users\8-Track\Desktop\mat16_104\CMPHeaders.pas=E:\Data\Users\8-Track\Desktop\mat16_104\dfltcmp.pas</Transaction> <Transaction>2021/12/28 11:45:15.000.992,=E:\Data\Users\8-Track\Desktop\mat16_104\FastMM4\FastMM4.pas</Transaction> - <Transaction>2021/12/28 11:46:18.000.764,=E:\Data\Users\8-Track\Desktop\mat16_104\FastMM4\FastMM4Messages.pas</Transaction> <Transaction>2021/12/28 11:46:18.000.719,=E:\Data\Users\8-Track\Desktop\mat16_104\FastMM4\FastMM4LockFreeStack.pas</Transaction> + <Transaction>2021/12/28 11:46:18.000.764,=E:\Data\Users\8-Track\Desktop\mat16_104\FastMM4\FastMM4Messages.pas</Transaction> <Transaction>2021/12/28 11:46:18.000.658,=E:\Data\Users\8-Track\Desktop\mat16_104\FastMM4\FastMM4DataCollector.pas</Transaction> <Transaction>2021/12/28 12:00:51.000.427,=E:\Data\Users\8-Track\Desktop\mat16_104\FastMM4\FastMM4Options.inc</Transaction> <Transaction>2022/01/09 18:33:00.000.494,=E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.pas</Transaction> @@ -29,17 +29,23 @@ <Transaction>2022/01/09 18:34:15.000.139,=E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.pas</Transaction> <Transaction>2022/01/09 18:34:40.000.164,E:\Data\Users\8-Track\Desktop\mat16_104\CNDHeaders.pas=E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.pas</Transaction> <Transaction>2022/01/16 12:24:41.000.082,=E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.pas</Transaction> - <Transaction>2022/01/16 12:28:51.000.440,E:\Data\Users\8-Track\Desktop\mat16_104\Set8bitFormatOnOpen.dfm=E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.dfm</Transaction> <Transaction>2022/01/16 12:28:51.000.440,E:\Data\Users\8-Track\Desktop\mat16_104\Set8bitFormatOnOpen.pas=E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.pas</Transaction> + <Transaction>2022/01/16 12:28:51.000.440,E:\Data\Users\8-Track\Desktop\mat16_104\Set8bitFormatOnOpen.dfm=E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.dfm</Transaction> <Transaction>2022/01/17 07:39:35.000.920,E:\Data\Users\8-Track\Desktop\mat16_104\mat_read.pas=</Transaction> - <Transaction>2022/01/17 07:59:06.000.518,=E:\Data\Users\8-Track\Desktop\mat16_104\dflt_Cell0_Mip0.bmp</Transaction> - <Transaction>2022/01/17 07:59:06.000.556,=E:\Data\Users\8-Track\Desktop\mat16_104\dflt_Cell0_Mip1.bmp</Transaction> <Transaction>2022/01/17 07:59:06.000.487,=E:\Data\Users\8-Track\Desktop\mat16_104\dflt_Cell0.BMP</Transaction> + <Transaction>2022/01/17 07:59:06.000.556,=E:\Data\Users\8-Track\Desktop\mat16_104\dflt_Cell0_Mip1.bmp</Transaction> + <Transaction>2022/01/17 07:59:06.000.518,=E:\Data\Users\8-Track\Desktop\mat16_104\dflt_Cell0_Mip0.bmp</Transaction> <Transaction>2022/01/17 12:06:43.000.549,=E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.pas</Transaction> - <Transaction>2022/01/17 12:07:17.000.697,E:\Data\Users\8-Track\Desktop\mat16_104\EditMat.dfm=E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.dfm</Transaction> <Transaction>2022/01/17 12:07:17.000.697,E:\Data\Users\8-Track\Desktop\mat16_104\EditMat.pas=E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.pas</Transaction> + <Transaction>2022/01/17 12:07:17.000.697,E:\Data\Users\8-Track\Desktop\mat16_104\EditMat.dfm=E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.dfm</Transaction> <Transaction>2022/01/23 17:21:32.000.083,=E:\Data\Users\8-Track\Desktop\mat16_104\BMP_IO.pas</Transaction> <Transaction>2022/01/27 19:34:50.000.726,=E:\Data\Users\8-Track\Desktop\mat16_104\Vcl.Graphics.pas</Transaction> <Transaction>2022/01/27 19:51:22.000.595,E:\Data\Users\8-Track\Desktop\mat16_104\Vcl.Graphics.pas=</Transaction> + <Transaction>2022/12/09 07:48:40.000.051,=E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.pas</Transaction> + <Transaction>2022/12/09 07:49:04.000.137,E:\Data\Users\8-Track\Desktop\mat16_104\GloabalVars.pas=E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.pas</Transaction> + <Transaction>2022/12/14 06:44:08.000.675,=E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.pas</Transaction> + <Transaction>2022/12/14 06:44:49.000.656,E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.dfm=E:\Data\Users\8-Track\Desktop\mat16_104\EditMTS.dfm</Transaction> + <Transaction>2022/12/14 06:44:49.000.656,E:\Data\Users\8-Track\Desktop\mat16_104\Unit1.pas=E:\Data\Users\8-Track\Desktop\mat16_104\EditMTS.pas</Transaction> + <Transaction>2022/12/15 07:15:57.989,E:\Data\Users\8-Track\Desktop\mat16_104\EditMTS.pas=</Transaction> </Transactions> </BorlandProject> diff --git a/Mat16.dres b/Mat16.dres deleted file mode 100644 index 1fee3bbc0dfb3447c91209fedea49431668e23c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4740 zcmeH~FKpv>6vsa|ZOTpoo)lmZ;FAJeDZsa7k~L*gPV#ovl$$)MlMDh34AROVz#t$X zARr(hz@Q)?z#t$XAi$uYz@Q)?AfTWipdc`?V5+>A>ovNoc7Fy2rshRo=lS>Nz2~Q& zpT7^_g&@oBA?gQm^ey}-BU$zpzwnwj{E3IfucE!-<$mo;o`3ytb0o@(cX);v*vWoY z^k;8J?l0n(g<vEI1XTh5Fqqv!d<E_dw7#tIB&LjPvnIPr$<ml?CgW4tI~GKOo}eXY z2y8(`P!cGzPb}Qs-En(+%XYiv=H`a$>uXl46^q4!G)*}_KW9FlGo4O}<CxKCL=;5~ z1_OG%9-U5yFboNT0N?j<T^Gl3ux*=Kt%hlu7>0qa>u8#Ws;Vf8LN1rvJtXVP3$88_ zmdTvOd`dcvIgiIA<1=Pw5tHG7c+h9m>k@U^4B8?6RzNps()K+<uR$O_{bL8OUdOd9 z9PwMPnpl+zRq<_>b&OI8UHq4dD#b#9g2bTY^URkS!`X(`aEaSas5Qov?LNgy3#H`V zABgk@hL_+^p%zK*+mLTa^cItBO@F(jxxS#joKv}&pv}hQC4QnIntzGvCKT#Z^0g5; zb4bqUf*y*Urr7vPAodaah<%0vnL~W@6PIz9Y1bq2EIL*hPgk)Ec??OPDl6<Tr4}Sq z{TY=;jNy(bI}s&$2F>bHtcIv&K*8`)$}WoTkk>47#VR?q!hDl4T5aj4YufV_ew=a~ zCD{E5X8VkCbAZ<9pgNKd%Oh_(<jR)BUXcKFnwuWS%MdH^F~`T02R2$*MQs=;c8P3~ zvFWZ^dMSw&GcNb(s{yT?LjzOJ;1mAIyL<W>Ir+4FZujXApOVv)!~7vXAJ4$yeEjF{ z$I&<Nv()jAaSM;%`HesJEaNf9_)hlju;&=>^NRQN-N*jGF%BH#z%iZ{<M;xO@!<#H z^ij?G|KFcT-}NOm_IoLjJ9%7Vcir0#4>k6c=zBTT*te-T^l^ti?#Xs?Qez+5w0E`i I<lp}P4bza5dH?_b diff --git a/Mat16.res b/Mat16.res index dda8ecb89890fc6e5bbbcc2515e75e3a89a93345..c1282a4c1d9f9ae01d8c4ff348713074067a98ca 100644 GIT binary patch delta 18 ZcmZ3Wx<GY80VBi2!u^Z}n++NB1pz&U1>*n! delta 18 ZcmZ3Wx<GY80VB)A!u^aUn++NB1pz(D1?vC+ diff --git a/Util.pas b/Util.pas index 665fb71..f1413e5 100644 --- a/Util.pas +++ b/Util.pas @@ -2,7 +2,7 @@ interface -uses Windows, Classes, ComCtrls, StdCtrls, SysUtils,vcl.graphics,vcl.controls; +uses Windows, Classes, ComCtrls, StdCtrls, SysUtils,vcl.graphics,vcl.controls,Vcl.Dialogs; function ExtractName(path: string): string; function ChangeExt(path: string; const newExt: string): string; @@ -16,6 +16,7 @@ procedure Blend(First,second:Tbitmap); procedure TransBlt(dst,src:Tbitmap; color:longint); function IsBMPPowerOfTwo(x,y: integer): boolean; function IsBMPmipsOK(Abitmap:tbitmap): boolean; +procedure PremultiplyAlpha(bmp:Tbitmap); implementation function ExtractName(path: string): string; @@ -204,11 +205,36 @@ procedure Blend(First,second:Tbitmap); end; +procedure PremultiplyAlpha(bmp:Tbitmap); +var + inrow32: PRGBQuad; + j,i:integer; +begin + for j := 0 to bmp.Height - 1 do + begin + inrow32 := bmp.ScanLine[j]; + for i := 0 to bmp.Width - 1 do + begin + with inrow32^ do + begin + // must pre-multiply the pixel with its alpha channel before drawing + rgbRed:= (rgbRed * rgbReserved) div 255; + rgbGreen:= (rgbGreen * rgbReserved) div 255; + rgbBlue:= (rgbBlue * rgbReserved) div 255; + inc(inrow32); + end; + end; + end; +end; + + function IsBMPmipsOK(Abitmap:tbitmap): boolean; begin if (Abitmap.Width >= 8) and (Abitmap.Height >=8) and (Abitmap.PixelFormat <> pf32bit) then result:=true; + + end; function IsBMPPowerOfTwo(x,y: integer): boolean; diff --git a/about_unit.dfm b/about_unit.dfm index d814836196e6a7564a04c08f97be12b714380d16..464d366dd908abe03f471634364c23e8ef6bce5c 100644 GIT binary patch delta 26 gcmZoT%+dfvTNqEua=4@>D;OCV8EwBP%ebBy0E5s7`~Uy| delta 26 gcmZoT%+dfvTNqEua`@$!DHs_T8E(HQ%ebBy0EN2=A^-pY diff --git a/gobform.dfm b/gobform.dfm index 451246ff86921407493ac5d9e6679172e0a93d31..233443481de49c259b7e41c35993fd3709d6ea25 100644 GIT binary patch delta 150 zcmdnSznP!^KNmxYyT4PIr)xNafxyCv{7r%>jNHySnW=dt;h8BV8O+-mHZJ03<l<n3 za91;I-p*LYY8RGSoSBr9%E7?E9^zD5Qj(v?<D8#YmReL2lJAsTz~YmdR>CB~9Fkwa jY{3Z8%T&qck(!yFQNkoMxtQHpR1jGM(8}a&1_lNIii|Cf delta 153 zcmdnYzm1>&KNmxYyT4PIr)xNafxwc9{7r(@jNHySnW=dt;h8BV8O)808y9gia<Q>O zxVem*w=<Tpy7}h;6(wi0^Ej23l;r0bf_V%K>>&_7JA^V~@kvc9VUl1D$uD4zW`vl* aRLSO%nwg$a!X!93o84FdYJ?Hg2nGQ6v@M4K diff --git a/gobform.pas b/gobform.pas index d844171..44eedd5 100644 --- a/gobform.pas +++ b/gobform.pas @@ -31,7 +31,7 @@ Tgobview = class(TForm) Label15: TLabel; Label16: TLabel; Label17: TLabel; - Button2: TButton; + ConvertToBmp: TButton; Label18: TLabel; Label_CMP: TLabel; procedure ListBox1Click(Sender: TObject); @@ -39,8 +39,7 @@ Tgobview = class(TForm) procedure opengob(filename: string); procedure openbaf(filename: string); procedure FormClose(Sender: TObject; var Action: TCloseAction); - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); + procedure ConvertToBmpClick(Sender: TObject); private { Private declarations } public @@ -55,7 +54,7 @@ Tgobview = class(TForm) implementation -uses Batch; +uses Batch,GloabalVars; {$R *.DFM} @@ -138,7 +137,7 @@ procedure Tgobview.FormShow(Sender: TObject); FileOffsets:=bafFilesToArray(filename, '.MAT'); tempList:=gobFileArrayToList(FileOffsets); ListBox1.Items.Assign(tempList); -tempList.Free; + tempList.Free; end; @@ -158,64 +157,28 @@ procedure Tgobview.opengob(filename: string); procedure Tgobview.FormClose(Sender: TObject; var Action: TCloseAction); begin listbox1.Clear; -end; + SetLength(FileOffsets,0); + SetLength(CMPOffsets,0); -procedure Tgobview.Button1Click(Sender: TObject); -begin - main.MainForm.Image1.Picture.Bitmap.Assign(image1.Picture.Bitmap); - // main.MainForm.LabelWidth.Caption := Label6.Caption; - main.MainForm.LabelHeight.Caption := Label17.Caption; - main.MainForm.LabelFormat.Caption := label15.Caption; - main.MainForm.Label3.Caption := '1'; - image1.Picture.Bitmap.FreeImage; - listbox1.Clear; - gobview.Close; end; -procedure Tgobview.Button2Click(Sender: TObject); +procedure Tgobview.ConvertToBmpClick(Sender: TObject); var i: integer; - savebitmap: Tbitmap; - bestcmp, gpath, mpath, fext, mname: string; begin - // savebitmap := Tbitmap.Create; - gpath := ExtractFilePath(Label_FileName.Caption); - fext := ExtractName(Label_FileName.Caption); - fext := ChangeFileExt(fext, ''); - gpath := gpath + fext; Screen.Cursor := crHourGlass; - CreateDir(gpath); BatchForm.Show; - BatchForm.ProgressBar1.Max := ListBox1.Items.Count; - for i := 0 to (ListBox1.Items.Count - 1) do begin BatchForm.ProgressBar1.Position := i; - //savebitmap := Tbitmap.Create; - //savebitmap:=nil; - bestcmp := GetbestCMP(listBox1.Items.Strings[i], Label_FileName.Caption); - // ReadCMPfromGOB(Label_FileName.Caption, bestcmp); - mainform.gridPalette.Repaint; - - // saveBitmap:=ReadMatfromGOB(Label_FileName.Caption, listBox1.Items.Strings[i]); - mname := ExtractName(listBox1.Items.Strings[i]); - mname := ChangeFileExt(mname, '.BMP'); - mpath := gpath + '\' + mname; - saveBitmap.SaveToFile(mpath); - - BatchForm.Memo1.Lines.Add('Saved ' + mpath + ' cmp:' + bestcmp); + BatchForm.Memo1.Lines.Add(GobMatSavetoBMP(Label_FileName.Caption, listBox1.Items.Strings[i],FileOffsets,CMPOffsets,true)); application.ProcessMessages; - - saveBitmap.Free; - end; BatchForm.Memo1.Lines.Add('-Done-'); Screen.Cursor := crDefault; - - //if Assigned(saveBitmap) then saveBitmap.Free; end; end. diff --git a/gobgoo.pas b/gobgoo.pas index ab6d2ef..47fa9bf 100644 --- a/gobgoo.pas +++ b/gobgoo.pas @@ -2,7 +2,7 @@ interface -uses Classes, SysUtils,Vcl.Dialogs,CMPHeaders; +uses Classes, SysUtils,Vcl.Dialogs,CMPHeaders,colormap,GloabalVars,MATImage,BMParrays,util,System.StrUtils; type @@ -48,6 +48,9 @@ function gobFilesToArray(gobfilename: string; filetype:string):TFileOffsets; function bafFilesToArray(gobfilename: string; filetype:string):TFileOffsets; function bafFilesToList(gobfilename: string; filetype:string):TstringList; function gobFileArrayToList(FileOffsets: TFileOffsets):TstringList; +function GobMatSavetoBMP(gobfile: string; fileinGobName: string;FileOffsets: TFileOffsets;CMPOffsets: TFileOffsets;MatInGob:boolean):String; +function GobMatToArray(gobfile: string; fileinGobName: string; + FileOffsets: TFileOffsets;CMPOffsets: TFileOffsets):TBMPArray; //procedure gobview.ListBox1Click(Sender: TObject); //TGOB2Directory=class(TContainerFile) //gh:TGob2Header; @@ -139,6 +142,103 @@ function GetGOBArrayOffset(FileOffsets: TFileOffsets; fileinGobName: string):lon {GOB2} +function GobMatToArray(gobfile: string; fileinGobName: string; + FileOffsets: TFileOffsets;CMPOffsets: TFileOffsets):TBMPArray; +var +bestcmp:string; +pos: integer; +gobCMP:TCMP; +Mat: TMAT; +begin + gobCMP:=TCMP.create; + {load jk or mots cmp} + if (UpperCase(ExtractFileExt(gobfile)) = '.GOB') or + (UpperCase(ExtractFileExt(gobfile)) = '.GOO') or + (UpperCase(ExtractFileExt(gobfile)) = '') then + begin + bestcmp := GetbestCMP(fileinGobName, JKPath); + pos:=GetGOBArrayOffset(CMPOffsets, bestcmp); + gobCMP.LoadCMPFromFile(jkpath, pos); + end; + {phantom menace cmp} + if (UpperCase(ExtractFileExt(gobfile)) = '.BAF') then + begin + gobCMP.LoadCMPFromBAFFile(gobfile, 336); + end; + + Mat:=TMAT.Create(TFormat.BMP); + Mat.SetCMP(gobCMP.GetRGB); + + pos:=GetGOBArrayOffset(FileOffsets, fileinGobName); + Result:= Mat.LoadFromFile(gobfile, pos); + + Mat.Free; + gobCMP.Free; + Mat:=nil; + +end; + + +function GobMatSavetoBMP(gobfile: string; fileinGobName: string;FileOffsets: TFileOffsets;CMPOffsets: TFileOffsets;MatInGob:boolean):String; +var +bestcmp:string; +pos: integer; +gobCMP:TCMP; +Mat: TMAT; +tempA:TBMPArray; +gpath, mpath: string; +begin + gobCMP:=TCMP.create; + {load jk or mots cmp} + if (UpperCase(ExtractFileExt(gobfile)) = '.GOB') or + (UpperCase(ExtractFileExt(gobfile)) = '.GOO') or + (UpperCase(ExtractFileExt(gobfile)) = '') then + begin + bestcmp := GetbestCMP(fileinGobName, JKPath); + pos:=GetGOBArrayOffset(CMPOffsets, bestcmp); + gobCMP.LoadCMPFromFile(jkpath, pos); + end; + {phantom menace cmp} + if (UpperCase(ExtractFileExt(gobfile)) = '.BAF') then + begin + gobCMP.LoadCMPFromBAFFile(gobfile, 336); + end; + + Mat:=TMAT.Create(TFormat.BMP); + Mat.SetCMP(gobCMP.GetRGB); + + if MatInGob then + begin + pos:=GetGOBArrayOffset(FileOffsets, fileinGobName); + tempA:= Mat.LoadFromFile(gobfile, pos); + gpath := ExtractFilePath(gobfile); + mpath := gpath + ExtractName(fileinGobName); + end + else + begin + tempA:= Mat.LoadFromFile(fileinGobName); + mpath := fileinGobName; + end; + + {8.3 filename bug workaround} + if ContainsText(mpath,'~1') then + mpath:= StringReplace(mpath, '~1', '_1', [rfReplaceAll, rfIgnoreCase]); + + tempA.SaveMTS(mpath); + + Result:='Saved MTS and bmp(s): ' + + ExtractName(fileinGobName) + + ' cmp: ' + bestcmp; + + Mat.Free; + tempA.Free; + gobCMP.Free; + Mat:=nil; + tempA:=nil + + end; + + procedure opengob(filename: string); var //Fi:TFInfo; i: integer;