Ticket #13101: frames-on-demand.txt

File frames-on-demand.txt, 5.3 KB (added by eriktorbjorn, 2 years ago)
Line 
1diff --git a/engines/sherlock/image_file.cpp b/engines/sherlock/image_file.cpp
2index 29d4cdfd4f..1ee7ee9a73 100644
3--- a/engines/sherlock/image_file.cpp
4+++ b/engines/sherlock/image_file.cpp
5@@ -38,6 +38,7 @@ ImageFile::ImageFile() {
6 }
7
8 ImageFile::ImageFile(const Common::String &name, bool skipPal, bool animImages) {
9+ _name = name;
10 Common::SeekableReadStream *stream = _vm->_res->load(name);
11
12 Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0);
13@@ -52,8 +53,39 @@ ImageFile::ImageFile(Common::SeekableReadStream &stream, bool skipPal) {
14 }
15
16 ImageFile::~ImageFile() {
17- for (uint idx = 0; idx < size(); ++idx)
18- (*this)[idx]._frame.free();
19+ for (uint idx = 0; idx < size(); ++idx) {
20+ if (_frames[idx]._decoded)
21+ _frames[idx]._frame.free();
22+ }
23+}
24+
25+ImageFrame& ImageFile::operator[](uint index) {
26+ if (!_frames[index]._decoded) {
27+ decodeFrame(_frames[index]);
28+ }
29+
30+ return _frames[index];
31+}
32+
33+uint ImageFile::size() {
34+ return _frames.size();
35+}
36+
37+void ImageFile::push_back(const ImageFrame &frame) {
38+ _frames.push_back(frame);
39+}
40+
41+void ImageFile::decodeFrame(ImageFrame &frame) {
42+ debug("%s: %dx%d", _name.c_str(), frame._width, frame._height);
43+
44+ Common::SeekableReadStream *stream = _vm->_res->load(_name);
45+ stream->seek(frame._pos);
46+ byte *data = new byte[frame._size + 4];
47+ stream->read(data, frame._size);
48+ Common::fill(data + frame._size, data + frame._size + 4, 0);
49+ frame.decompressFrame(data, IS_ROSE_TATTOO);
50+ delete[] data;
51+ delete stream;
52 }
53
54 void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool animImages) {
55@@ -92,12 +124,22 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool
56 frame._size = frame._width * frame._height;
57 }
58
59- // Load data for frame and decompress it
60- byte *data1 = new byte[frame._size + 4];
61- stream.read(data1, frame._size);
62- Common::fill(data1 + frame._size, data1 + frame._size + 4, 0);
63- frame.decompressFrame(data1, IS_ROSE_TATTOO);
64- delete[] data1;
65+ frame._pos = stream.pos();
66+
67+ if (_name.empty()) {
68+ // Load data for frame and decompress it
69+ frame._decoded = true;
70+ byte *data1 = new byte[frame._size + 4];
71+ stream.read(data1, frame._size);
72+ Common::fill(data1 + frame._size, data1 + frame._size + 4, 0);
73+ frame.decompressFrame(data1, IS_ROSE_TATTOO);
74+ delete[] data1;
75+ } else {
76+debug("%s: %dx%d", _name.c_str(), frame._width, frame._height);
77+ frame._decoded = false;
78+
79+ stream.seek(MIN(stream.pos() + frame._size, stream.size()));
80+ }
81
82 push_back(frame);
83 }
84@@ -302,6 +344,10 @@ ImageFile3DO::ImageFile3DO(Common::SeekableReadStream &stream, bool isRoomData)
85 }
86 }
87
88+void ImageFile3DO::decodeFrame(ImageFrame &frame) {
89+ error("ImageFile3DO: Frame should already have been decoded");
90+}
91+
92 void ImageFile3DO::load(Common::SeekableReadStream &stream, bool isRoomData) {
93 uint32 headerId = 0;
94
95@@ -354,6 +400,7 @@ void ImageFile3DO::loadAnimationFile(Common::SeekableReadStream &stream) {
96
97 celDataSize = stream.readUint16BE();
98
99+ frame._decoded = true;
100 frame._width = stream.readUint16BE() + 1; // 2 bytes BE width
101 frame._height = stream.readByte() + 1; // 1 byte BE height
102 frame._paletteBase = 0;
103@@ -586,6 +633,7 @@ void ImageFile3DO::load3DOCelFile(Common::SeekableReadStream &stream) {
104 // Set up frame
105 ImageFrame imageFrame;
106
107+ imageFrame._decoded = true;
108 imageFrame._width = ccbWidth;
109 imageFrame._height = ccbHeight;
110 imageFrame._paletteBase = 0;
111@@ -712,6 +760,7 @@ void ImageFile3DO::load3DOCelRoomData(Common::SeekableReadStream &stream) {
112 {
113 ImageFrame imageFrame;
114
115+ imageFrame._decoded = true;
116 imageFrame._width = ccbWidth;
117 imageFrame._height = ccbHeight;
118 imageFrame._paletteBase = 0;
119@@ -956,6 +1005,7 @@ void ImageFile3DO::loadFont(Common::SeekableReadStream &stream) {
120 // create frame
121 ImageFrame imageFrame;
122
123+ imageFrame._decoded = true;
124 imageFrame._width = widthTablePtr[curChar];
125 imageFrame._height = header_fontHeight;
126 imageFrame._paletteBase = 0;
127diff --git a/engines/sherlock/image_file.h b/engines/sherlock/image_file.h
128index 0ae7cc1dcb..6cd7a2370d 100644
129--- a/engines/sherlock/image_file.h
130+++ b/engines/sherlock/image_file.h
131@@ -37,6 +37,8 @@ namespace Sherlock {
132 class SherlockEngine;
133
134 struct ImageFrame {
135+ uint32 _pos;
136+ byte _decoded;
137 uint32 _size;
138 uint16 _width, _height;
139 int _paletteBase;
140@@ -76,9 +78,11 @@ struct ImageFrame {
141 int sDrawYOffset(int scaleVal) const;
142 };
143
144-class ImageFile : public Common::Array<ImageFrame> {
145+class ImageFile {
146 private:
147 static SherlockEngine *_vm;
148+ Common::Array<ImageFrame> _frames;
149+ Common::String _name;
150
151 /**
152 * Load the data of the sprite
153@@ -89,7 +93,13 @@ private:
154 * Gets the palette at the start of the sprite file
155 */
156 void loadPalette(Common::SeekableReadStream &stream);
157+protected:
158+ virtual void decodeFrame(ImageFrame &frame);
159 public:
160+ ImageFrame& operator[](uint index);
161+ uint size();
162+ void push_back(const ImageFrame &frame);
163+
164 byte _palette[256 * 3];
165 public:
166 ImageFile();
167@@ -152,6 +162,9 @@ private:
168 */
169 void loadFont(Common::SeekableReadStream &stream);
170
171+protected:
172+ virtual void decodeFrame(ImageFrame &frame);
173+
174 public:
175 ImageFile3DO(const Common::String &name, ImageFile3DOType imageFile3DOType);
176 ImageFile3DO(Common::SeekableReadStream &stream, bool isRoomData = false);