1 unit f_addresource_texture
;
3 {$INCLUDE ../shared/a_modes.inc}
8 LCLIntf
, LCLType
, LMessages
, SysUtils
, Variants
, Classes
,
9 Graphics
, Controls
, Forms
, Dialogs
, f_addresource
,
10 StdCtrls
, ExtCtrls
, utils
, Imaging
, ImagingTypes
, ImagingUtility
,
14 TAddTextureForm
= class (TAddResourceForm
)
15 PanelTexPreview
: TPanel
;
22 procedure FormActivate(Sender
: TObject
);
23 procedure lbResourcesListClick(Sender
: TObject
);
24 procedure eTextureNameChange(Sender
: TObject
);
25 procedure cbWADListChange(Sender
: TObject
);
26 procedure cbSectionsListChange(Sender
: TObject
);
27 procedure bCloseClick(Sender
: TObject
);
28 procedure bAddTextureClick(Sender
: TObject
);
29 procedure bAddCloseClick(Sender
: TObject
);
38 AddTextureForm
: TAddTextureForm
;
40 function IsAnim(Res
: String): Boolean;
41 function GetFrame(Res
: String; var Data
: Pointer; var DataLen
: Integer;
42 var Width
, Height
: Word): Boolean;
47 BinEditor
, WADEDITOR
, WADSTRUCT
, f_main
, g_textures
, CONFIG
, g_map
,
51 TTGAHeader
= packed record
55 ColorMapSpec
: Array [0..4] of Byte;
56 OrigX
: Array [0..1] of Byte;
57 OrigY
: Array [0..1] of Byte;
58 Width
: Array [0..1] of Byte;
59 Height
: Array [0..1] of Byte;
66 function IsAnim(Res
: String): Boolean;
74 Sign
: Array [0..4] of Char;
83 // Читаем файл и ресурс в нем:
84 g_ProcessResourceStr(Res
, WADName
, SectionName
, ResourceName
);
86 WAD
:= TWADEditor_1
.Create();
88 if (not WAD
.ReadFile(WADName
)) or
89 (not WAD
.GetResource(SectionName
, ResourceName
, Data
, Size
)) then
97 // Проверка сигнатуры. Если есть - это WAD внутри WAD:
98 CopyMemory(@Sign
[0], Data
, 5);
100 if not (Sign
= DFWAD_SIGNATURE
) then
107 // Пробуем прочитать данные:
108 if not WAD
.ReadMemory(Data
, Size
) then
118 Sections
:= WAD
.GetSectionList();
120 if Sections
= nil then
126 // Ищем в секциях "TEXT":
128 for a
:= 0 to High(Sections
) do
129 if Sections
[a
] = 'TEXT' then
135 // Ищем в секциях лист текстур - "TEXTURES":
136 for a
:= 0 to High(Sections
) do
137 if Sections
[a
] = 'TEXTURES' then
149 // Получаем ресурсы секции "TEXT":
150 Resources
:= WAD
.GetResourcesList('TEXT');
152 if Resources
= nil then
158 // Ищем в них описание анимации - "AINM":
160 for a
:= 0 to High(Resources
) do
161 if Resources
[a
] = 'ANIM' then
169 // Если все получилось, то это аним. текстура:
173 function GetFrame(Res
: String; var Data
: Pointer; var DataLen
: Integer;
174 var Width
, Height
: Word): Boolean;
180 ResourceName
: String;
189 g_ProcessResourceStr(Res
, WADName
, SectionName
, ResourceName
);
191 WAD
:= TWADEditor_1
.Create();
193 if not WAD
.ReadFile(WADName
) then
199 // Читаем WAD-ресурс из WAD:
200 if not WAD
.GetResource(SectionName
, ResourceName
, AnimWAD
, Len
) then
208 // Читаем WAD в WAD'е:
209 if not WAD
.ReadMemory(AnimWAD
, Len
) then
216 // Читаем описание анимации:
217 if not WAD
.GetResource('TEXT', 'ANIM', TextData
, Len
) then
225 config
:= TConfig
.CreateMem(TextData
, Len
);
227 // Читаем ресурс - лист текстур:
228 if not WAD
.GetResource('TEXTURES', config
.ReadStr('', 'resource', ''), Data
, Len
) then
238 Height
:= config
.ReadInt('', 'frameheight', 0);
239 Width
:= config
.ReadInt('', 'framewidth', 0);
250 function CreateBitMap(Data
: Pointer; DataSize
: Cardinal): TBitMap
;
270 if not LoadImageFromMemory(Data
, DataSize
, img
) then
272 e_WriteLog('Invalid image format?', MSG_WARNING
);
277 Height
:= img
.height
;
279 ImageSize
:= Width
*Height
*(ColorDepth
div 8);
281 BitMap
:= TBitMap
.Create();
282 BitMap
.PixelFormat
:= pf24bit
;
284 BitMap
.Width
:= Width
;
285 BitMap
.Height
:= Height
;
287 // Копируем в BitMap:
288 ii
:= BitMap
.RawImage
.Data
;
289 for y
:= 0 to height
-1 do
291 for x
:= 0 to width
-1 do
293 clr
:= GetPixel32(img
, x
, y
);
294 // HACK: Lazarus's TBitMap doesn't seem to have a working 32 bit mode, so
295 // mix color with pink background. FUCK!
296 clr
.r
:= ClampToByte(((255 - clr
.a
) * BG_R
+ clr
.a
* clr
.r
) div 255);
297 clr
.g
:= ClampToByte(((255 - clr
.a
) * BG_G
+ clr
.a
* clr
.g
) div 255);
298 clr
.b
:= ClampToByte(((255 - clr
.a
) * BG_B
+ clr
.a
* clr
.b
) div 255);
299 // TODO: check for ARGB/RGBA/BGRA/ABGR somehow?
300 ii
^ := clr
.b
; Inc(ii
);
301 ii
^ := clr
.g
; Inc(ii
);
302 ii
^ := clr
.r
; Inc(ii
);
303 // ii^ := clr.a; Inc(ii);
310 function ShowAnim(Res
: String): TBitMap
;
316 ResourceName
: String;
320 TextureData
: Pointer;
325 // Читаем WAD файл и ресурс в нем:
326 g_ProcessResourceStr(Res
, WADName
, SectionName
, ResourceName
);
328 WAD
:= TWADEditor_1
.Create();
329 WAD
.ReadFile(WADName
);
330 WAD
.GetResource(SectionName
, ResourceName
, AnimWAD
, Len
);
333 // Читаем описание анимации:
334 WAD
.ReadMemory(AnimWAD
, Len
);
335 WAD
.GetResource('TEXT', 'ANIM', TextData
, Len
);
337 config
:= TConfig
.CreateMem(TextData
, Len
);
339 // Читаем лист текстур:
340 WAD
.GetResource('TEXTURES', config
.ReadStr('', 'resource', ''), TextureData
, Len
);
342 if (TextureData
<> nil) and
343 (WAD
.GetLastError
= DFWAD_NOERROR
) then
345 // Создаем BitMap из листа текстур:
346 Result
:= CreateBitMap(TextureData
, Len
);
348 // Размеры одного кадра - виден только первый кадр:
349 Result
.Height
:= config
.ReadInt('', 'frameheight', 0);
350 Result
.Width
:= config
.ReadInt('', 'framewidth', 0);
356 FreeMem(TextureData
);
361 function ShowTGATexture(ResourceStr
: String): TBitMap
;
363 TextureData
: Pointer;
367 ResourceName
: String;
374 g_ProcessResourceStr(ResourceStr
, WADName
, SectionName
, ResourceName
);
376 WAD
:= TWADEditor_1
.Create();
377 if not WAD
.ReadFile(WADName
) then
383 // Читаем ресурс текстуры в нем:
384 WAD
.GetResource(SectionName
, ResourceName
, TextureData
, Len
);
388 // Создаем на его основе BitMap:
389 Result
:= CreateBitMap(TextureData
, Len
);
391 FreeMem(TextureData
);
394 procedure TAddTextureForm
.FormActivate(Sender
: TObject
);
398 cbWADList
.Items
.Add(_lc
[I_WAD_SPECIAL_TEXS
]);
400 eTextureName
.Text := '';
401 iPreview
.Canvas
.FillRect(iPreview
.Canvas
.ClipRect
);
403 bOK
.Visible
:= False;
404 bCancel
.Visible
:= False;
407 procedure TAddTextureForm
.lbResourcesListClick(Sender
: TObject
);
415 if lbResourcesList
.ItemIndex
= -1 then
417 if FResourceName
= '' then
419 if cbWADList
.Text = _lc
[I_WAD_SPECIAL_TEXS
] then
422 g_ProcessResourceStr(FFullResourceName
, @wad
, nil, nil);
423 if wad
= _lc
[I_WAD_SPECIAL_TEXS
] then
426 if IsAnim(FFullResourceName
) then
427 Texture
:= ShowAnim(FFullResourceName
)
429 Texture
:= ShowTGATexture(FFullResourceName
);
431 if Texture
= nil then
433 iPreview
.Canvas
.FillRect(iPreview
.Canvas
.ClipRect
);
434 iPreview
.Canvas
.CopyRect(Texture
.Canvas
.ClipRect
, Texture
.Canvas
, Texture
.Canvas
.ClipRect
);
438 procedure TAddTextureForm
.eTextureNameChange(Sender
: TObject
);
444 // Убираем старые выделения:
445 for a
:= 0 to lbResourcesList
.Items
.Count
-1 do
446 lbResourcesList
.Selected
[a
] := False;
449 if (lbResourcesList
.Items
.Count
= 0) or
450 (eTextureName
.Text = '') then
455 for a
:= 0 to lbResourcesList
.Items
.Count
-1 do
456 if LowerCase(Copy(lbResourcesList
.Items
[a
], 1,
457 Length(eTextureName
.Text))) =
458 LowerCase(eTextureName
.Text) then
460 lbResourcesList
.Selected
[a
] := True;
464 // Показываем первую текстуру из найденных:
465 lbResourcesList
.TopIndex
:= a
;
466 lbResourcesList
.OnClick(nil);
473 procedure TAddTextureForm
.cbWADListChange(Sender
: TObject
);
475 if cbWADList
.Text = _lc
[I_WAD_SPECIAL_TEXS
] then
477 cbSectionsList
.Clear();
478 cbSectionsList
.Items
.Add('..');
485 procedure TAddTextureForm
.cbSectionsListChange(Sender
: TObject
);
487 if cbWADList
.Text = _lc
[I_WAD_SPECIAL_TEXS
] then
489 lbResourcesList
.Clear();
490 lbResourcesList
.Items
.Add(TEXTURE_NAME_WATER
);
491 lbResourcesList
.Items
.Add(TEXTURE_NAME_ACID1
);
492 lbResourcesList
.Items
.Add(TEXTURE_NAME_ACID2
);
499 procedure TAddTextureForm
.bCloseClick(Sender
: TObject
);
504 procedure TAddTextureForm
.bAddTextureClick(Sender
: TObject
);
509 for i
:= 0 to lbResourcesList
.Count
-1 do
510 if lbResourcesList
.Selected
[i
] then
512 AddTexture(utf2win(cbWADlist
.Text), utf2win(cbSectionsList
.Text),
513 utf2win(lbResourcesList
.Items
[i
]), False);
514 lbResourcesList
.Selected
[i
] := False;
518 procedure TAddTextureForm
.bAddCloseClick(Sender
: TObject
);
520 bAddTextureClick(bAddTexture
);