File: resource_patcher.h

package info (click to toggle)
scummvm 2.9.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 450,268 kB
  • sloc: cpp: 4,297,604; asm: 28,322; python: 12,901; sh: 11,219; java: 8,477; xml: 7,843; perl: 2,633; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (162 lines) | stat: -rw-r--r-- 4,069 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#ifndef SCI_RESOURCE_RESOURCE_PATCHER_H
#define SCI_RESOURCE_RESOURCE_PATCHER_H

#include "common/language.h"
#include "sci/sci.h"
#include "sci/resource/resource.h"
#include "sci/resource/resource_intern.h"

namespace Sci {

enum ResourcePatchOp {
	// Using high bytes to make it less likely that accidental raw data will be
	// treated like an operator instead of an error
	kSkipBytes = 0xF0,
	kReplaceBytes,
	kInsertBytes,
	kReplaceNumber,
	kAdjustNumber,
	kInsertNumber,
	kReplaceFill,
	kInsertFill,
	kEndOfPatch
};

enum SciMedia : uint;

struct GameResourcePatch {
	/**
	 * The game to patch.
	 */
	SciGameId gameId;

	/**
	 * The media to patch. Use SCI_MEDIA_ALL for all.
	 */
	SciMedia media;

	/**
	 * The language to patch. Use `Common::UNK_LANG` to apply the patch to all
	 * languages.
	 */
	Common::Language gameLanguage;

	/**
	 * The resource type to patch.
	 */
	ResourceType resourceType;

	/**
	 * The resource number to patch.
	 */
	uint16 resourceNumber;

	/**
	 * Patch instructions to apply to the resource.
	 */
	const byte *patchData;

	/**
	 * Set to true if the patch resource is actually a new resource, rather than
	 * a patch for an existing resource.
	 */
	bool isNewResource;
};

/**
 * A basic class for generating patched resource data at runtime.
 */
class ResourcePatcher : public ResourceSource {
public:
	ResourcePatcher(const SciGameId gameId, const bool isCD, const Common::Platform platform, const Common::Language gameLanguage);

	~ResourcePatcher() override {}

	/**
	 * Finds and applies a patch to the given resource.
	 *
	 * @returns true if a patch was applied.
	 */
	bool applyPatch(Resource &resource) const;

	/**
	 * Adds new resources from the patch table to the resource manager. This
	 * is needed since otherwise tests for these resources via `kResCheck`
	 * would fail, and so they would never actually be loaded.
	 */
	void scanSource(ResourceManager *resMan) override;

	/**
	 * Load a resource. Since resources using this source are patched explicitly
	 * after they get loaded by any other resource source, this method does
	 * nothing.
	 */
	void loadResource(ResourceManager *resMan, Resource *res) override {}

private:
	struct PatchSizes {
		/**
		 * The minimum number of bytes required in the source data.
		 */
		uint32 expected;

		/**
		 * The difference in size between the original data and the patched
		 * data.
		 */
		int32 delta;

		PatchSizes(uint32 exp, int32 d) {
			expected = exp;
			delta = d;
		}
	};

	typedef Common::Array<GameResourcePatch> PatchList;

	/**
	 * The list of patches that should apply to the currently loaded game.
	 */
	PatchList _patches;

	/**
	 * Patches the given Resource using patch data from the given
	 * GameResourcePatch.
	 */
	void patchResource(Resource &resource, const GameResourcePatch &patch) const;

	/**
	 * Calculates expected and extra data sizes from the patch data.
	 */
	PatchSizes calculatePatchSizes(const byte *patchData) const;

	/**
	 * Reads a block size from the patch data, validates it, and advances the
	 * patch data pointer.
	 */
	int32 readBlockSize(const byte * &patchData) const;
};
} // End of namespace Sci

#endif	// SCI_RESOURCE_RESOURCE_PATCHER_H