MediaImages.pas
上传用户:ctlcnc
上传日期:2021-12-10
资源大小:4933k
文件大小:13k
源码类别:

2D图形编程

开发平台:

Delphi

  1. unit MediaImages;
  2. //---------------------------------------------------------------------------
  3. // MediaImages.pas                                      Modified: 08-Jan-2007
  4. // Resource management utility for Asphyre images                 Version 1.0
  5. //---------------------------------------------------------------------------
  6. // Important Notice:
  7. //
  8. // If you modify/use this code or one of its parts either in original or
  9. // modified form, you must comply with Mozilla Public License v1.1,
  10. // specifically section 3, "Distribution Obligations". Failure to do so will
  11. // result in the license breach, which will be resolved in the court.
  12. // Remember that violating author's rights is considered a serious crime in
  13. // many countries. Thank you!
  14. //
  15. // !! Please *read* Mozilla Public License 1.1 document located at:
  16. //  http://www.mozilla.org/MPL/
  17. //
  18. // If you require any clarifications about the license, feel free to contact
  19. // us or post your question on our forums at: http://www.afterwarp.net
  20. //---------------------------------------------------------------------------
  21. // The contents of this file are subject to the Mozilla Public License
  22. // Version 1.1 (the "License"); you may not use this file except in
  23. // compliance with the License. You may obtain a copy of the License at
  24. // http://www.mozilla.org/MPL/
  25. //
  26. // Software distributed under the License is distributed on an "AS IS"
  27. // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
  28. // License for the specific language governing rights and limitations
  29. // under the License.
  30. //
  31. // The Original Code is MediaImages.pas.
  32. //
  33. // The Initial Developer of the Original Code is M. Sc. Yuriy Kotsarenko.
  34. // Portions created by M. Sc. Yuriy Kotsarenko are Copyright (C) 2007,
  35. // Afterwarp Interactive. All Rights Reserved.
  36. //---------------------------------------------------------------------------
  37. interface
  38. //---------------------------------------------------------------------------
  39. uses
  40.  Direct3D9, D3DX9, Types, SysUtils, AsphyreXML, MediaUtils
  41.  {$IFDEF DebugMode}, AsphyreDebug{$ENDIF};
  42. //---------------------------------------------------------------------------
  43. type
  44.  PImageDesc = ^TImageDesc;
  45.  TImageDesc = record
  46.   Identifier  : string;          // unique image identifier
  47.   DescType    : TImageDescType;  // type of desc: image, surface or dynamic
  48.   Format      : TD3DFormat;      // target pixel format
  49.   MipLevels   : Cardinal;        // number of mipmap levels
  50.   PatSize     : TPoint;          // pattern size
  51.   PatCount    : Integer;         // number of patterns
  52.   PatPadSize  : TPoint;          // pattern padding size
  53.   ColorKey    : Cardinal;        // color key, unused if alpha > 0
  54.   DepthStencil: Boolean;         // whether to use depth/stencil buffer
  55.   Size        : TPoint;          // the size of surface/dynamic texture
  56.   Textures    : array of string; // the location of textures used in the image
  57.  end;
  58. //---------------------------------------------------------------------------
  59.  TImageGroup = class
  60.  private
  61.   Data: array of TImageDesc;
  62.   FName  : string;
  63.   FOption: string;
  64.   function GetCount(): Integer;
  65.   function GetItem(Num: Integer): PImageDesc;
  66.   function NewItem(): PImageDesc;
  67.   procedure ParseItem(Node: TXMLNode);
  68.  public
  69.   property Name: string read FName;
  70.   property Option: string read FOption;
  71.   property Count: Integer read GetCount;
  72.   property Item[Num: Integer]: PImageDesc read GetItem; default;
  73.   function Find(const Text: string): PImageDesc;
  74.   procedure ParseXML(Node: TXMLNode);
  75.   constructor Create(const AName: string);
  76.  end;
  77. //---------------------------------------------------------------------------
  78.  TImageGroups = class
  79.  private
  80.   Data: array of TImageGroup;
  81.   function GetCount(): Integer;
  82.   function GetItem(Num: Integer): TImageGroup;
  83.   function GetGroup(const Name: string): TImageGroup;
  84.   function NewGroup(const Name: string): TImageGroup;
  85.   function GetTotal(): Integer;
  86.  public
  87.   property Count: Integer read GetCount;
  88.   property Item[Num: Integer]: TImageGroup read GetItem;
  89.   property Group[const Name: string]: TImageGroup read GetGroup;
  90.   property Total: Integer read GetTotal;
  91.   function IndexOf(Name: string): Integer;
  92.   procedure Clear();
  93.   function Find(const uid: string; Option: string): PImageDesc;
  94.   procedure ParseLink(const Link: string);
  95.   destructor Destroy(); override;
  96.  end;
  97. //---------------------------------------------------------------------------
  98. var
  99.  ImageGroups: TImageGroups = nil;
  100. //---------------------------------------------------------------------------
  101. implementation
  102. //---------------------------------------------------------------------------
  103. constructor TImageGroup.Create(const AName: string);
  104. begin
  105.  inherited Create();
  106.  FName:= LowerCase(AName);
  107. end;
  108. //---------------------------------------------------------------------------
  109. function TImageGroup.GetCount(): Integer;
  110. begin
  111.  Result:= Length(Data);
  112. end;
  113. //---------------------------------------------------------------------------
  114. function TImageGroup.GetItem(Num: Integer): PImageDesc;
  115. begin
  116.  if (Num >= 0)and(Num < Length(Data)) then
  117.   Result:= @Data[Num] else Result:= nil;
  118. end;
  119. //---------------------------------------------------------------------------
  120. function TImageGroup.Find(const Text: string): PImageDesc;
  121. var
  122.  LoText: ShortString;
  123.  i: Integer;
  124. begin
  125.  LoText:= LowerCase(Text);
  126.  Result:= nil;
  127.  for i:= 0 to Length(Data) - 1 do
  128.   if (Data[i].Identifier = LoText) then
  129.    begin
  130.     Result:= @Data[i];
  131.     Break;
  132.    end;
  133. end;
  134. //---------------------------------------------------------------------------
  135. function TImageGroup.NewItem(): PImageDesc;
  136. var
  137.  Index: Integer;
  138. begin
  139.  Index:= Length(Data);
  140.  SetLength(Data, Index + 1);
  141.  FillChar(Data[Index], SizeOf(TImageDesc), 0);
  142.  // configure defaults
  143.  Data[Index].Format      := D3DFMT_UNKNOWN;
  144.  Data[Index].MipLevels   := D3DX_DEFAULT;
  145.  Data[Index].DepthStencil:= False;
  146.  Data[Index].DescType    := idtImage;
  147.  Data[Index].PatCount    := 1;
  148.  Result:= @Data[Index];
  149. end;
  150. //---------------------------------------------------------------------------
  151. procedure TImageGroup.ParseItem(Node: TXMLNode);
  152. var
  153.  Desc  : PImageDesc;
  154.  Aux   : TXMLNode;
  155.  Name  : string;
  156.  i, Num: Integer;
  157.  Child : TXMLNode;
  158. begin
  159.  // (1) Determine resource type.
  160.  Name:= LowerCase(Node.Name);
  161.  if (Name <> 'image') then Exit;
  162.  // (2) Create image description.
  163.  Desc:= NewItem();
  164.  Desc.Identifier:= LowerCase(Node.FieldValue['uid']);
  165.  Desc.DescType  := ParseImageType(LowerCase(Node.FieldValue['type']));
  166.  {$IFDEF DebugMode}
  167.  DebugLog('  ++ Image described as "' + Desc.Identifier + '".');
  168.  {$ENDIF}
  169.  // (3) Parse "format" node.
  170.  Aux:= Node.ChildNode['format'];
  171.  if (Aux <> nil) then
  172.   begin
  173.    Desc.Format   := ParseFormat(LowerCase(Aux.FieldValue['type']));
  174.    Desc.MipLevels:= ParseCardinal(LowerCase(Aux.FieldValue['miplevels']),
  175.     D3DX_DEFAULT);
  176.    Desc.DepthStencil:= ParseBoolean(LowerCase(Aux.FieldValue['depthstencil']));
  177.   end;
  178.  // (4) Parse "pattern" node
  179.  Aux:= Node.ChildNode['pattern'];
  180.  if (Aux <> nil) then
  181.   begin
  182.    Desc.PatSize.X   := ParseInt(Aux.FieldValue['width'], 0);
  183.    Desc.PatSize.Y   := ParseInt(Aux.FieldValue['height'], 0);
  184.    Desc.PatCount    := ParseInt(Aux.FieldValue['count'], 1);
  185.    Desc.PatPadSize.X:= ParseInt(Aux.FieldValue['padx'], 0);
  186.    Desc.PatPadSize.Y:= ParseInt(Aux.FieldValue['pady'], 0);
  187.   end;
  188.  {$IFDEF DebugMode}
  189.  DebugLog('   -> Pattern Size: ' + IntToStr(Desc.PatSize.X) + 'x' +
  190.   IntToStr(Desc.PatSize.Y));
  191.  DebugLog('   -> Number of patterns: ' + IntToStr(Desc.PatCount));
  192.  {$ENDIF}
  193.  // (5) Parse "colorkey" node.
  194.  Aux:= Node.ChildNode['colorkey'];
  195.  if (Aux <> nil) then
  196.   Desc.ColorKey:= ParseColor(LowerCase(Aux.FieldValue['value']), 0);
  197.  // (6) Parse "textures" node.
  198.  Aux:= Node.ChildNode['textures'];
  199.  if (Aux <> nil) then
  200.   begin
  201.    SetLength(Desc.Textures, ParseInt(Aux.FieldValue['count'], 1));
  202.    {$IFDEF DebugMode}
  203.    DebugLog('   -> Having ' + IntToStr(Length(Desc.Textures)) +
  204.     ' textures in total.');
  205.    {$ENDIF}
  206.    for i:= 0 to Aux.ChildCount - 1 do
  207.     begin
  208.      Child:= Aux.Child[i];
  209.      Num:= ParseInt(Child.FieldValue['num']);
  210.      if (Num >= 0)and(Num < Length(Desc.Textures)) then
  211.       Desc.Textures[Num]:= LowerCase(Child.FieldValue['source']);
  212.      {$IFDEF DebugMode}
  213.      DebugLog('   --> Using texture #' + IntToStr(Num) + ' from: ' +
  214.       Desc.Textures[Num]);
  215.      {$ENDIF}
  216.     end;
  217.   end;
  218.  // (7) Parse "size" node.
  219.  Aux:= Node.ChildNode['size'];
  220.  if (Aux <> nil) then
  221.   begin
  222.    Desc.Size.X:= ParseInt(Aux.FieldValue['width'], 0);
  223.    Desc.Size.Y:= ParseInt(Aux.FieldValue['height'], 0);
  224.    {$IFDEF DebugMode}
  225.    DebugLog('   -> Size defined as ' + IntToStr(Desc.Size.X) + 'x' +
  226.     IntToStr(Desc.Size.Y));
  227.    {$ENDIF}
  228.   end;
  229. end;
  230. //---------------------------------------------------------------------------
  231. procedure TImageGroup.ParseXML(Node: TXMLNode);
  232. var
  233.  i: Integer;
  234. begin
  235.  if (LowerCase(Node.Name) <> 'image-group') then Exit;
  236.  FName  := LowerCase(Node.FieldValue['name']);
  237.  FOption:= LowerCase(Node.FieldValue['option']);
  238.  {$IFDEF DebugMode}
  239.  DebugLog(' + New image group "' + FName + '", option "' + FOption + '".');
  240.  {$ENDIF}
  241.  for i:= 0 to Node.ChildCount - 1 do
  242.   ParseItem(Node.Child[i]);
  243. end;
  244. //---------------------------------------------------------------------------
  245. destructor TImageGroups.Destroy();
  246. begin
  247.  Clear();
  248.  inherited;
  249. end;
  250. //---------------------------------------------------------------------------
  251. function TImageGroups.GetCount: Integer;
  252. begin
  253.  Result:= Length(Data);
  254. end;
  255. //---------------------------------------------------------------------------
  256. function TImageGroups.GetItem(Num: Integer): TImageGroup;
  257. begin
  258.  if (Num >= 0)and(Num < Length(Data)) then
  259.   Result:= Data[Num] else Result:= nil;
  260. end;
  261. //---------------------------------------------------------------------------
  262. function TImageGroups.IndexOf(Name: string): Integer;
  263. var
  264.  i: Integer;
  265. begin
  266.  Name:= LowerCase(Name);
  267.  Result:= -1;
  268.  for i:= 0 to Length(Data) - 1 do
  269.   if (Data[i].Name = Name) then
  270.    begin
  271.     Result:= i;
  272.     Break;
  273.    end;
  274. end;
  275. //---------------------------------------------------------------------------
  276. function TImageGroups.GetGroup(const Name: string): TImageGroup;
  277. var
  278.  Index: Integer;
  279. begin
  280.  Result:= nil;
  281.  Index := IndexOf(Name);
  282.  if (Index <> -1) then Result:= Data[Index];
  283. end;
  284. //---------------------------------------------------------------------------
  285. procedure TImageGroups.Clear();
  286. var
  287.  i: Integer;
  288. begin
  289.  for i:= 0 to Length(Data) - 1 do
  290.   if (Data[i] <> nil) then
  291.    begin
  292.     Data[i].Free();
  293.     Data[i]:= nil;
  294.    end;
  295.  SetLength(Data, 0);
  296. end;
  297. //---------------------------------------------------------------------------
  298. function TImageGroups.GetTotal(): Integer;
  299. var
  300.  i: Integer;
  301. begin
  302.  Result:= 0;
  303.  for i:= 0 to Length(Data) - 1 do
  304.   Inc(Result, Data[i].Count);
  305. end;
  306. //---------------------------------------------------------------------------
  307. function TImageGroups.Find(const uid: string; Option: string): PImageDesc;
  308. var
  309.  i: Integer;
  310. begin
  311.  Result:= nil;
  312.  Option:= LowerCase(Option);
  313.  for i:= 0 to Length(Data) - 1 do
  314.   if (Option = '')or(Data[i].Option = '')or(LowerCase(Data[i].Option) = Option) then
  315.    begin
  316.     Result:= Data[i].Find(uid);
  317.     if (Result <> nil) then Break;
  318.    end;
  319. end;
  320. //---------------------------------------------------------------------------
  321. function TImageGroups.NewGroup(const Name: string): TImageGroup;
  322. var
  323.  Index: Integer;
  324. begin
  325.  Index:= Length(Data);
  326.  SetLength(Data, Index + 1);
  327.  Data[Index]:= TImageGroup.Create(Name);
  328.  Result:= Data[Index];
  329. end;
  330. //---------------------------------------------------------------------------
  331. procedure TImageGroups.ParseLink(const Link: string);
  332. var
  333.  nName: string;
  334.  Root : TXMLNode;
  335.  gName: string;
  336.  Group: TImageGroup;
  337.  Text : string;
  338.  i: Integer;
  339. begin
  340.  {$IFDEF DebugMode}
  341.  DebugLog('Begin entry [image groups]: ' + Link);
  342.  {$ENDIF}
  343.  Root:= LoadLinkXML(Link);
  344.  if (Root = nil) then Exit;
  345.  if (LowerCase(Root.Name) <> 'unires')  then
  346.   begin
  347.    {$IFDEF DebugMode}
  348.    DebugLog('Root node is not UNIRES, exiting.');
  349.    {$ENDIF}
  350.    Root.Free();
  351.    Exit;
  352.   end;
  353.  for i:= 0 to Root.ChildCount - 1 do
  354.   begin
  355.    nName:= LowerCase(Root.Child[i].Name);
  356.    if (nName = 'image-group') then
  357.     begin
  358.      gName:= LowerCase(Root.Child[i].FieldValue['name']);
  359.      if (Length(gName) > 0) then
  360.       begin
  361.        Group:= GetGroup(gName);
  362.        if (Group = nil) then Group:= NewGroup(gName);
  363.        Group.ParseXML(Root.Child[i]);
  364.       end;
  365.     end;
  366.    if (nName = 'resource') then
  367.     begin
  368.      Text:= Root.Child[i].FieldValue['source'];
  369.      if (Length(Text) > 0) then ParseLink(Text);
  370.     end;
  371.   end;
  372.  Root.Free();
  373.  {$IFDEF DebugMode}
  374.  DebugLog('End entry [image groups]: ' + Link);
  375.  {$ENDIF}
  376. end;
  377. //---------------------------------------------------------------------------
  378. initialization
  379.  ImageGroups:= TImageGroups.Create();
  380. //---------------------------------------------------------------------------
  381. finalization
  382.  ImageGroups.Free();
  383.  ImageGroups:= nil;
  384. //---------------------------------------------------------------------------
  385. end.