📄 arom.pas
字号:
unit aROM;
interface
uses Classes, SysUtils, VirtualTable, DB, Variants, jvJCLUtils, StrUtils, Forms,
Graphics, JPEG, jvGIF, Types, Dialogs, Math,RXFileUtil,SZCRC32;
const
rtGIF = 'GIF';
rtJPG = 'JPG';
rtBMP = 'BMP';
rtMIDI = 'MID';
rtWAV = 'WAV';
rtMP3 = 'MP3';
EmptyChar = #0;
type
TaROM = class(TObject)
DS: TVirtualTable;
private
MemStream: TMemoryStream;
ROMStream: TStringStream;
function LoadGIFs: boolean;
function LoadJPEGs: boolean;
function LoadBMPs: boolean;
function LoadWAVs: boolean;
function LoadMIDs: boolean;
function LoadMP3s: boolean;
public
constructor Create;
destructor Destroy; override;
function LoadROMFile(FilePath: string): string;
function WriteROMFile(FilePath: string): string;
function LoadResources: boolean;
function CalcMaxSize(Size, EOF: integer): integer;
//===========================
procedure ResRecalcPreview;
procedure ResSaveToFile;
procedure ResSaveToEditor;
procedure ResLoadFromFile;
procedure ResLoadFromEditor;
procedure ResRestore;
procedure ResCalcCRC32;
end;
procedure StretchPicture(x: integer; Picture: TPicture);
function BytesToWord(Bytes: string): word;
function BytesToDWord(Bytes: string): dword;
var
ROM: TaROM;
implementation
uses aMain;
{ TaROM }
//====================================================
function BytesToWord(Bytes: string): word;
begin
Result := HexToInt(IntToHex(Ord(Bytes[1]), 2) + IntToHex(Ord(Bytes[2]), 2));
end;
//---------------
function BytesToDWord(Bytes: string): dword;
begin
Result := HexToInt(IntToHex(Ord(Bytes[4]), 2) + IntToHex(Ord(Bytes[3]), 2) +
IntToHex(Ord(Bytes[2]), 2) + IntToHex(Ord(Bytes[1]), 2));
end;
//====================================================
procedure StretchPicture(x: integer; Picture: TPicture);
var
Jpeg1, Jpeg2: TGraphic;
TempBitmap: Graphics.TBitmap;
CanvasRect: TRect;
begin
TempBitmap := Graphics.TBitmap.Create;
if Picture.graphic <> nil then
begin
if Picture.graphic is TJpegImage then
begin
Jpeg1 := TJPEGImage.Create;
Jpeg2 := TJPEGImage.Create;
end
else
if Picture.graphic is Graphics.TBitmap then
begin
Jpeg1 := Graphics.TBitmap.Create;
Jpeg2 := Graphics.TBitmap.Create;
end
else
begin
Jpeg1 := TJvGIFImage.Create;
Jpeg2 := TJvGIFImage.Create;
end;
end
else
exit;
try
Jpeg1.Assign(Picture);
if JPeg1.Height < JPeg1.Width then
begin
TempBitmap.Width := x;
TempBitmap.Height := Trunc(JPeg1.Height * (x / jpeg1.Width));
end
else
begin
TempBitmap.Height := x;
TempBitmap.Width := Trunc(JPeg1.Width * (x / jpeg1.Height));
end;
CanvasRect := Rect(0, 0, TempBitmap.Width, TempBitmap.Height);
TempBitMap.Canvas.StretchDraw(CanvasRect, JPeg1);
Picture.Assign(TempBitmap);
finally
TempBitmap.Free;
Jpeg1.Free;
Jpeg2.Free;
end;
end;
function TaROM.CalcMaxSize(Size, EOF: integer): integer;
var
i: integer;
begin
i := 0;
while Ord(Self.ROMStream.datastring[EOF + i]) = 0 do
begin
Inc(i);
end;
if i > 0 then
Result := Size + i - 1
else
Result := Size;
end;
//=====================================================
constructor TaROM.Create;
begin
inherited;
MemStream := TMemoryStream.Create;
ROMStream := TStringStream.Create('');
end;
destructor TaROM.Destroy;
begin
MemStream.Free;
ROMStream.Free;
inherited;
end;
function TaROM.LoadBMPs: boolean;
var
S, N, O: DWord;
CurrOffset: integer;
BFoundOffset, EFoundOffset: integer;
ResNo: integer;
Pic: TPicture;
TempStr: TStringStream;
//---
TempBMP: TBitmap;
//---
BOF: string;
EOF: string;
SubType: string;
begin
BOF := 'BM';
EOF := '';
CurrOffset := 1;
ResNo := 0;
try
try
Pic := TPicture.Create;
while CurrOffset <> -1 do
begin
StartWait;
Application.ProcessMessages;
BFoundOffset := StrUtils.PosEx(BOF, Self.ROMStream.DataString,
CurrOffset);
if BFoundOffset <= 0 then
begin
break;
end;
TempBMP := TBitmap.Create;
SubType := 'BMP';
//===========================================================
S := BytesToDWORD(Copy(ROMStream.DataString, BFoundOffset + 2, 4));
O := BytesToDWORD(Copy(ROMStream.DataString, BFoundOffset + 10, 4));
N := BytesToDWORD(Copy(ROMStream.DataString, BFoundOffset + 14, 4));
if (S > 1000000) or (N <> 40) or (S < 32) or (O = 0) then
begin
CurrOffset := BFoundOffset + 1;
Continue;
end;
EFoundOffset := BFoundOffset + S + 2;
if EFoundOffset <= 0 then
begin
break;
end;
TempStr := TStringStream.Create(
Copy(Self.ROMStream.DataString, BFoundOffset, EFoundOffset -
BFoundOffset));
TempStr.Position := 0;
try
TempStr.Position := 0;
TempBMP.LoadFromStream(TempStr);
except
TempStr.Free;
CurrOffSet := BFoundOffset + 1;
continue;
end;
TempStr.Free;
//================================
ResNo := ResNo + 1;
Self.DS.Append;
DS.FieldByName('VTROMResResID').AsString := rtBMP + '-' + IntToStr(ResNo);
DS.FieldByName('VTROMResType').AsString := rtBMP;
DS.FieldByName('VTROMResBIN').AsString :=
Copy(Self.ROMStream.DataString, BFoundOffset, EFoundOffset -
BFoundOffset);
// TempStr := TStringStream.Create(
// Copy(Self.ROMStream.DataString, BFoundOffset, EFoundOffset - BFoundOffset));
DS.FieldByName('VTROMResProps').AsString :=
' H:' + IntToStr(TempBMP.Height) + ' W:' + IntToStr(TempBMP.Width) +
' (' + SubType + ')';
DS.FieldByName('VTROMResMaxSize').AsInteger :=
CalcMaxSize(Length(DS.FieldByName('VTROMResBIN').AsString),
EFoundOffset);
DS.FieldByName('VTROMResOffset').AsInteger := BFoundOffset;
TempStr := TStringStream.Create(DS.FieldByName('VTROMResBIN').AsString);
TempStr.Position := 0;
if (TempBMP.Empty) or (TempBMP.Height = 0) or (TempBMP.Width = 0) then
begin
// ShowMessage('Corrupted GIF!');
// TempGif.SaveToFile('D:\Corrupted.gif');
DS.FieldByName('VTROMResProps').AsString :=
'硒栳赅
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -