File: resource_patcher.h

package info (click to toggle)
scummvm 2.2.0%2Bdfsg1-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 227,768 kB
  • sloc: cpp: 2,525,134; ansic: 144,108; asm: 28,422; sh: 9,109; python: 8,774; xml: 6,003; perl: 3,523; java: 1,547; makefile: 948; yacc: 720; lex: 437; javascript: 336; objc: 81; sed: 22; php: 1
file content (151 lines) | stat: -rw-r--r-- 3,844 bytes parent folder | download
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
/* 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 2
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#ifndef SCI_RESOURCE_PATCHER_H
#define SCI_RESOURCE_PATCHER_H

#include "common/language.h"
#include "sci/sci.h"
#include "sci/resource.h"
#include "sci/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
};

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

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

	/**
	 * The resource ID to patch.
	 */
	ResourceId resourceId;

	/**
	 * 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 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 an 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