ElderImagerySky.pas 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. {
  2. Vampyre Imaging Library
  3. by Marek Mauder
  4. https://github.com/galfar/imaginglib
  5. https://imaginglib.sourceforge.io
  6. - - - - -
  7. This Source Code Form is subject to the terms of the Mozilla Public
  8. License, v. 2.0. If a copy of the MPL was not distributed with this
  9. file, You can obtain one at https://mozilla.org/MPL/2.0.
  10. }
  11. { This unit contains image format loader/saver for SKY file format used
  12. in Daggerfall to store sky backdrops.}
  13. unit ElderImagerySky;
  14. {$I ImagingOptions.inc}
  15. interface
  16. uses
  17. SysUtils, ImagingTypes, Imaging, ElderImagery;
  18. type
  19. { Class for loading and saving of images in SKY format. It is
  20. 8 bit indexed format found in Daggerfall, and maybe other old Bethesda
  21. games. Files are named SKY##.DAT and each contains two sets of 32 images
  22. (512 by 220 pixels), each with its palette. First set contains sky
  23. without sun, second set sky with sun. }
  24. TSKYFileFormat = class(TElderFileFormat)
  25. protected
  26. procedure Define; override;
  27. function LoadData(Handle: TImagingHandle; var Images: TDynImageDataArray;
  28. OnlyFirstLevel: Boolean): Boolean; override;
  29. public
  30. function TestFormat(Handle: TImagingHandle): Boolean; override;
  31. end;
  32. implementation
  33. const
  34. SSKYFormatName = 'Daggerfall Sky Images';
  35. SSKYMasks = '*.dagsky,sky??.dat';
  36. SkyWidth = 512;
  37. SkyHeight = 220;
  38. SkyCount = 64;
  39. DataOffset = 549120;
  40. PalFileSize = 776;
  41. SkyImageSize = SkyWidth * SkyHeight;
  42. SkyFileId: array[0..5] of Byte = ($08, $03, $00, $00, $23, $B1);
  43. { TSKYFileFormat class implementation }
  44. procedure TSKYFileFormat.Define;
  45. begin
  46. inherited;
  47. FFeatures := [ffLoad, ffMultiImage];
  48. FName := SSKYFormatName;
  49. AddMasks(SSKYMasks);
  50. end;
  51. function TSKYFileFormat.LoadData(Handle: TImagingHandle;
  52. var Images: TDynImageDataArray; OnlyFirstLevel: Boolean): Boolean;
  53. var
  54. I: Integer;
  55. Pal24: TPalette24Size256;
  56. procedure CopyPalette(Dest: PPalette32);
  57. var
  58. I: Integer;
  59. begin
  60. for I := 0 to 255 do
  61. begin
  62. Dest[I].A := 255;
  63. Dest[I].R := Pal24[I].B;
  64. Dest[I].G := Pal24[I].G;
  65. Dest[I].B := Pal24[I].R;
  66. end;
  67. end;
  68. begin
  69. SetLength(Images, SkyCount);
  70. for I := 0 to SkyCount - 1 do
  71. begin
  72. NewImage(SkyWidth, SkyHeight, ifIndex8, Images[I]);
  73. // Read corresponding palette from file
  74. GetIO.Seek(Handle, PalFileSize * (I mod 32) + 8, smFromBeginning);
  75. GetIO.Read(Handle, @Pal24, SizeOf(Pal24));
  76. CopyPalette(Images[I].Palette);
  77. // Now read image pixels
  78. GetIO.Seek(Handle, DataOffset + I * SkyImageSize, smFromBeginning);
  79. GetIO.Read(Handle, Images[I].Bits, SkyImageSize);
  80. end;
  81. Result := True;
  82. end;
  83. function TSKYFileFormat.TestFormat(Handle: TImagingHandle): Boolean;
  84. var
  85. Id: array[0..5] of Byte;
  86. ReadCount: Integer;
  87. begin
  88. Result := False;
  89. if Handle <> nil then
  90. with GetIO do
  91. begin
  92. FillChar(ID, SizeOf(Id), 0);
  93. ReadCount := Read(Handle, @Id, SizeOf(Id));
  94. Seek(Handle, -ReadCount, smFromCurrent);
  95. Result := (ReadCount = SizeOf(Id)) and
  96. CompareMem(@Id, @SkyFileId, SizeOf(SkyFileId));
  97. end;
  98. end;
  99. {
  100. File Notes:
  101. -- TODOS ----------------------------------------------------
  102. - nothing now
  103. -- 0.26.3 Changes/Bug Fixes ---------------------------------
  104. - Initial version created.
  105. }
  106. end.